sie*_*z0r 11 python properties metaclass python-module python-sphinx
我有一个应该有的模块@property,我通过将类设置为模块来解决这个问题.我从这个答案中得到了一个想法:懒惰的模块变量 - 可以做到吗?
我希望这个可重复且易于使用,所以我为它制作了一个元类.这就像一个魅力.
问题是,当使用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
Run Code Online (Sandbox Code Playgroud)
以及用于生成/查看Sphinx文档的复制粘贴:
sphinx-apidoc . -o doc --full
sphinx-build doc html
xdg-open html/module.html
Run Code Online (Sandbox Code Playgroud)
最重要的部分是记录班级的属性.奖励指向还记录原始模块成员.
编辑:该类应记录为它所在的模块.该类以这种方式使用,因此应该以这种方式出现在Sphinx中.
期望输出的示例:
Module Foo
TestClass docstring.
some_property
Property docstring.
meth()
meth doc
Run Code Online (Sandbox Code Playgroud)
编辑2:我找到了一些可能有助于找到解决方案的东西.foo拥有包含以下内容的常规模块时:
#: Property of foo
prop = 'test'
Run Code Online (Sandbox Code Playgroud)
Sphinx记录如下:
foo.prop = 'test'
Property of foo
Run Code Online (Sandbox Code Playgroud)
如果prop是类的属性,则同样有效.我还没弄清楚为什么它在我的特殊情况下不起作用.
这是我的理解。
理论是:让你的类的突变体像模块一样工作,这种(有点hacky)方式使sphinx认为他不需要(解析)来自模块的属性(因为它是类级范例)。所以,对于sphinx来说,TestClass是一个模块。
首先,为了确保罪魁祸首是使类充当模块的代码 - 让我们删除它:
class ClassAsModule(type):
pass
Run Code Online (Sandbox Code Playgroud)
我们将在文档中看到:
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.
Run Code Online (Sandbox Code Playgroud)
如您所见,sphinx 读取该属性没有任何问题。这里没什么特别的。
您的问题的可能解决方案是避免使用@property装饰器并将其替换为调用property类构造函数。例如:
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
Run Code Online (Sandbox Code Playgroud)
对于此代码,sphinx 生成:
package Package
script Module
TestClass docstring.
package.script.get_some_property(self)
Property docstring.
package.script.meth(self)
meth doc
Run Code Online (Sandbox Code Playgroud)
也许答案是废话,但我希望它能为您指明正确的方向。
| 归档时间: |
|
| 查看次数: |
3149 次 |
| 最近记录: |