问题描述
python 3.9 的一个小附加组件是
在 3.9 版更改:类方法现在可以包装其他描述符,例如 property()。
这在多种情况下都很有用,例如作为 Using property() on classmethods 的解决方案或为了通过配方创建本质上是延迟评估的类属性
class A:
@classmethod
@property
@cache
def lazy_class_attribute(cls):
"""Method docstring."""
return expensive_computation(cls)
这在 python 中运行良好,导入类,实例化它或它的子类不会导致 expensive_computation
发生,但是似乎 pydoc
和 sphinx
都不会仅在他们尝试获取文档字符串时导致执行 expensive_computation
,但不显示此 @classmethod
的任何文档字符串。
问题:是否有可能 - 从 python (*) 内部 - 懒惰地评估在构建文档时不会执行的类属性/属性?
(*) Stop Sphinx from Executing a cached classmethod property 中提出的一种解决方法,感谢 /u/jsbueno,包括根据环境变量修改函数体:
def lazy_class_attribute(cls):
"""Method docstring."""
if os.environ.get("GENErating_DOCS",False):
return
return expensive_computation(cls)
我非常喜欢这种解决方法,特别是因为它允许在记录时呈现不同的输出。 (例如,我的类具有基于类名的路径属性。如果不同的用户执行相同的脚本,路径将不同,因为他们的主文件夹不同。)
但是有两个问题:
class MetaClass:
@property
@cache
def _expensive_function(cls):
"""some expensive function"""
class BaseClass(Metaclass=MetaClass):
lazy_attribute: type = classmethod(MetaClass._expensive_funcion)
"""lazy_attribute docstring"""
PS:顺便说一下,@classmethod@property
和 attribute
之间在功能上有什么区别吗?他们看起来非常相似。目前我能看出的唯一区别是,如果该属性需要访问其他 @classmethod
,我们需要按上述方式移动元类中的所有内容。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)