2013-04-09 21 views
10

Mam moduł, który powinien mieć @property, rozwiązałem go, ustawiając klasę jako moduł. Pomyślałem o tej odpowiedzi: Lazy module variables--can it be done?Właściwości modułu dokumentu Sphinx

Chciałem, aby to było powtarzalne i łatwe w użyciu, więc zrobiłem dla niego metaclass. Działa to jak urok.

Problem polega na tym, że podczas używania sfinksa do generowania właściwości dokumentacji nie są dokumentowane. Wszystko inne jest udokumentowane zgodnie z oczekiwaniami. Nie mam pojęcia, jak to naprawić, może to jest problem ze Sphinx?

Moduł:

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 

I copy-paste do generowania/zobaczyć dokumentację Sphinx:

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

Najbardziej istotne jest to, aby udokumentować właściwości klasy. Punkty premiowe za dokumentowanie oryginalnych członków modułu.

Edycja: Klasa powinny udokumentować, jak to jest w module Klasa jest używany w ten sposób, a tym samym sposób ten powinien pojawić się w Sfinksa..

Przykład pożądaną wydajność:

Module Foo 
    TestClass docstring. 

    some_property 
     Property docstring. 

    meth() 
     meth doc 

EDIT 2: I stwierdzono, że co może pomóc w znalezieniu rozwiązania. Kiedy o normalnej moduł foo o następującej treści:

#: Property of foo 
prop = 'test' 

Sphinx to dokumenty takie jak:

foo.prop = 'test' 
    Property of foo 

Te same prace, jeżeli prop jest atrybutem klasy. Nie domyśliłem się, dlaczego to nie działa w moim szczególnym przypadku.

+0

Twój kod nie działa. 'ModMeta' nie jest zdefiniowany. Czy mógłbyś opublikować działający kod? – jterrace

+0

@jterrace Copy-paste fail. Naprawiono teraz ;-) – siebz0r

+0

Usunięto moją odpowiedź, ponieważ oryginalny kod miał '__metaclass_' zamiast' __metaclass__', co powodowało, że nie działał. – jterrace

Odpowiedz

1

Oto moje zrozumienie.

Teoria brzmi: co mutantem klasa akt jak moduł (nieco hacky) sposób sprawia sfinks myślę, że nie trzeba (do analizy) właściwości z modułów (bo to paradygmat poziomie klasy). Tak więc, dla sfinksa, TestClass jest modułem.

Przede wszystkim, aby upewnić się, że winowajcą jest kod dla dokonywania klasy działać jak moduł - niech usunąć go:

class ClassAsModule(type): 
    pass 

zobaczymy w docs:

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. 

Jak widzisz, sfinks czytał nieruchomość bez żadnych problemów. Nic specjalnego tutaj.


Możliwe rozwiązanie Twojego problemu jest, aby unikać @property dekorator i zastąpić go nazywając property klasy konstruktora. Na przykład.:

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 

dla tego kodu sfinks generuje:

package Package 
    script Module 
     TestClass docstring. 

      package.script.get_some_property(self) 
       Property docstring. 

      package.script.meth(self) 
       meth doc 

może być odpowiedź jest kawałek nonsens, ale mam nadzieję, że będzie to punkt, który we właściwym kierunku.

+0

Niestety nie ma sensu korzystanie z właściwości i zsynchronizowanej dokumentacji. – siebz0r

+0

Tak, ale ważne jest, aby zrozumieć, że dekorator '@ property' jest tylko cukrem składniowym. Definiowanie właściwości poprzez tworzenie instancji klasy 'property', ponieważ zasugerowałem prace tak samo, jak użycie dekoratora. Ale, oczywiście, w tym przypadku dokumentacja pokazuje nieco inny obraz. – alecxe

+0

Przyznam ci nagrodę, ponieważ nikt nie otrzyma tych punktów. Nie dostanę zwrotu pieniędzy i nie spodziewam się wkrótce akceptowanej odpowiedzi, więc wydawało mi się, że jest to "najlepsza" rzecz. – siebz0r

0

Sposób Odkryłam, że działa najlepiej jest, aby zachować zawartość pliku tak samo jakbyś pisania regularną moduł, a następnie na koniec wymienić moduł zarodkowych w 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__) 

dokumentację Text :

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

Module docstring. 

mymod.meth() 

    meth doc 

mymod.some_property = None 

    Property docstring. 

dla wersji Sfinksa używam (v1.1.3), wygląda na to trzeba zastosować właściwość konstruktora jawnie (nie można go używać jako dekorator) i docstring ma przejść do pliku na najwyższym poziomie, w wierszu po skonstruowaniu lub wywołanie, które tworzy właściwość (nie działa jako docstring wewnątrz gettera właściwości). Źródło jest jednak nadal dość czytelne.