2013-04-09 3 views
10

私はモジュールが@propertyであるはずです。モジュールとしてクラスを設定することでこれを解決しました。私はこの答えからアイデアを得ました:Lazy module variables--can it be done?Sphinxドキュメントモジュールのプロパティ

私はこれを繰り返して使いやすく、メタクラスを作ったかったのです。これは魅力のように機能します。

問題は、ドキュメントプロパティを生成するためにSphinxを使用してもドキュメント化されないということです。他のすべては、期待どおりに文書化されています。これを修正する方法がわかりませんが、これはSphinxの問題ですか?

モジュール:

import sys 
import types 

class ClassAsModule(type): 
    def __new__(cls, name, bases, attrs): 
     # Make sure the name of the class is the module name. 
     name = attrs.pop('__module__') 
     # Create a class. 
     cls = type.__new__(cls, name, bases, attrs) 
     # Instantiate the class and register it. 
     sys.modules[name] = cls = cls(name) 
     # Update the dict so dir works properly 
     cls.__dict__.update(attrs) 

class TestClass(types.ModuleType): 
    """TestClass docstring.""" 
    __metaclass__ = ClassAsModule 
    @property 
    def some_property(self): 
     """Property docstring.""" 
     pass 
    def meth(): 
     """meth doc""" 
     pass 

、コピー&ペーストSphinxのドキュメントを表示/生成する:

sphinx-apidoc . -o doc --full 
sphinx-build doc html 
xdg-open html/module.html 

最も本質的な部分は、クラスのプロパティを文書化することです。ボーナスは元のモジュールメンバーも文書化します。

EDIT:このクラスは、この方法で使用されるため、このようにSphinxに表示されるはずです。所望の出力の

例:

Module Foo 
    TestClass docstring. 

    some_property 
     Property docstring. 

    meth() 
     meth doc 

EDIT 2:は、私は解決策を見つけるのを助けることができる何かを見つけました。

#: Property of foo 
prop = 'test' 

Sphinxのドキュメント、このような:次の内容の定期的なモジュールfoo持つpropはクラスの属性である場合

foo.prop = 'test' 
    Property of foo 

を同じ作品。私はそれが私の特別な場合にはうまくいかない理由を理解していない。

+0

コードが機能しません。 'ModMeta'は定義されていません。作業コードを投稿してください。 – jterrace

+0

@jterraceコピー貼り付けに失敗します。今修正されました;-) – siebz0r

+0

元のコードが '__metaclass__'の代わりに' __metaclass_'を持っていたので、私の答えを削除しました。 – jterrace

答えて

1

ここに私の理解があります。

この理論は、あなたのクラスがモジュールのように動作するようにしています。これは、スフィンクスがモジュールからのプロパティを解析する必要がないと考えるようにします(クラスレベルのパラダイムであるためです)。 )。したがって、スフィンクスの場合、TestClassはモジュールです。すべての

まず、犯人はモジュールのようなクラスを作用させるためのコードがあることを確認する - のは、それを削除してみましょう:私たちは、ドキュメントに表示されます

class ClassAsModule(type): 
    pass 

package Package 
    script Module 

    class package.script.ClassAsModule 
     Bases: type 

    class package.script.TestClass 
     Bases: module 

     TestClass docstring. 

     meth() 
      meth doc 

     some_property 
      Property docstring. 

ご覧のとおり、スフィンクスは何の問題もなく物件を読みました。ここに特別なものはありません。あなたの問題のため


解決策@propertyデコレータを使用して回避しpropertyクラスのコンストラクタを呼び出すと、それを置き換えることです。例えば。:

package Package 
    script Module 
     TestClass docstring. 

      package.script.get_some_property(self) 
       Property docstring. 

      package.script.meth(self) 
       meth doc 

は答えはナンセンスの一部であるかもしれないが、私はそれが正しい方向にあなたを指していただければ幸いです:このコードのスフィンクスについては

import sys 
import types 

class ClassAsModule(type): 
    def __new__(cls, name, bases, attrs): 
     # Make sure the name of the class is the module name. 
     name = attrs.pop('__module__') 
     # Create a class. 
     cls = type.__new__(cls, name, bases, attrs) 
     # Instantiate the class and register it. 
     sys.modules[name] = cls = cls(name) 
     # Update the dict so dir works properly 
     cls.__dict__.update(attrs) 


class TestClass(types.ModuleType): 
    """TestClass docstring.""" 
    __metaclass__ = ClassAsModule 

    def get_some_property(self): 
     """Property docstring.""" 
     pass 

    some_property = property(get_some_property) 

    def meth(self): 
     """meth doc""" 
     pass 

が生成されます。

+0

悲しいことに、これはプロパティの使用とドキュメントの同期が失われています。 – siebz0r

+0

ええ、しかし、 '@ property'デコレータは単なる構文砂糖であることを理解することが重要です。私が提案したように、 'property'クラスをインスタンス化することによってプロパティを定義することは、実際にデコレータを使うのと同じ方法で動作します。しかし、確かに、この場合、ドキュメンテーションはやや異なった画像を示しています。 – alecxe

+0

他に誰もそれらのポイントを受け取ることはないので、私はあなたに賞金を与えています。私は払い戻しをしないだろうし、すぐに受け入れられる答えを期待していないので、それは「最良の」ことのように思えた。 – siebz0r

0

最高の作品あなたが定期的にモジュールを書いたかのように同じファイルの内容を維持することである私が見つけた方法は、その後、最後にsys.modulesにおける胚モジュール置き換える:

"""Module docstring. """ 

import sys 
import types 

def _some_property(self): 
    pass 
some_property = property(_some_property) 
"""Property docstring.""" 

def meth(): 
    """meth doc""" 
    pass 

def _make_class_module(name): 
    mod = sys.modules[name] 
    cls = type('ClassModule', (types.ModuleType,), mod.__dict__) 
    clsmod = cls(name) 
    clsmod.__dict__.update(mod.__dict__) 
    clsmod.__wrapped__ = mod 
    sys.modules[name] = clsmod 
_make_class_module(__name__) 

テキストドキュメントを:私は(v1.1.3デベロッパー)を使用していスフィンクスのバージョンについては

mymod Module 
************ 

Module docstring. 

mymod.meth() 

    meth doc 

mymod.some_property = None 

    Property docstring. 

、あなたは(あなたはデコレータとして使用することはできません)、明示的にプロパティコンストラクタを適用しているように見えます、そしてドキュメンテーション文字列を持っていますトップレベルのファイル、コンストラクターの後の行に入るまたはプロパティを作成する呼び出し(プロパティゲッター内のドキュメントストリングとして機能しません)。しかし、ソースはかなり読みやすいです。