如何在 Python 3.9 / 3.10 中记录 Classmethod 属性?

问题描述

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 发生,但是似乎 pydocsphinx 都不会仅在他们尝试获取文档字符串时导致执行 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)

我非常喜欢这种解决方法,特别是因为它允许在记录时呈现不同的输出。 (例如,我的类具有基于类名的路径属性。如果不同的用户执行相同的脚本,路径将不同,因为他们的主文件夹不同。)

但是有两个问题:

  1. 这种方法依赖于在 python 之外做的事情,imo 在理想的世界中应该不需要在 python 本身之外做
  2. 为了在文档中获取文档字符串,我们似乎最终不得不做一些不直观的事情
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"""

enter image description here

PS:顺便说一下,@classmethod@propertyattribute 之间在功能上有什么区别吗?他们看起来非常相似。目前我能看出的唯一区别是,如果该属性需要访问其他 @classmethod,我们需要按上述方式移动元类中的所有内容

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)