python - 根据类属性更 retrofit 饰器中类方法的文档字符串

标签 python python-sphinx python-decorators

让我们从这里开始:

class Example(object):

    change_docstring = True

    @add_to_docstring(" (additional content!)")
    def example_method(self):
        """Example docstring."""
        pass

我想做的是允许 @add_to_docstring装饰器将其参数字符串附加到方法的文档字符串中 only 如果 change_docstring属性是 True .我不想将任何其他东西传递给装饰器。

这个解决方案有效,但它并不是我正在寻找的。

def add_to_docstring(text):

    def decorator(original_method):

        def wrapper(self):
            """wrapper docstring."""
            wrapper.__doc__ = original_method.__doc__

            if self.change_docstring:
                wrapper.__doc__ += text

            return original_method(self)

        return wrapper

    return decorator

让我解释一下。

以上解决方案仅在 example_method 时更改文档字符串被执行。加载类、方法等时,文档字符串不会改变。

>>> Example.example_method.__doc__
"wrapper docstring."
>>>
>>> Example().example_method()
>>> Example.example_method.__doc__
"Example docstring. (additional content!)"

这就是我希望上述命令的输出:

>>> Example.example_method.__doc__
"Example docstring. (additional content!)"

同样,我不想将任何其他内容传递给装饰器。

更新

为了进一步说明,这是为了允许装饰器更改方法的文档字符串,并将该更改反射(reflect)在 Sphinx 生成的文档中。 Sphinx 加载所有内容并收集文档字符串,但它不会做任何其他事情。

基于选定的解决方案,我在装饰器模块中添加了一个模块变量,并公开了一个方法来禁用装饰器中的文档字符串更改功能。为了普遍禁用该功能,我随后在我的 Sphinx 中调用了该禁用功能 conf.py像这样的文件:

# import the decorators module
from some_modules import decorators
# disable the docstring change feature
decorators.disable_docstring_change()

然后可以在项目中的任何方法上使用装饰器,并且将启用或禁用文档字符串更改。

最佳答案

Martijn Pieter's answer 中所述到“从类定义中的列表理解访问类变量”,如果您在类的新范围内,则无法访问类属性。该答案主要关注类范围内的理解和生成器表达式,但同样适用于普通函数,包括装饰器。

解决这个问题的一个简单方法是使 change_docstring 成为全局的,并在类之前定义它,这样您就可以轻松地逐个类地设置它。另一种选择是将其作为装饰器的参数,但您说过您不希望这样做。这是一个适用于 Python 2 和 3 的简短演示。

def add_to_docstring(text):
    def decorator(original_method):
        def wrapper(self):
            return original_method(self)
        wrapper.__doc__ = original_method.__doc__
        if change_docstring:
            wrapper.__doc__ += text
        return wrapper
    return decorator

change_docstring = True
class Example(object):
    @add_to_docstring(" (additional content!)")
    def example_method(self):
        """Example docstring."""
        pass

change_docstring = False
class Other(object):
    @add_to_docstring(" (more content!)")
    def example_method(self):
        """Other docstring."""
        pass

print(Example.example_method.__doc__)
print(Other.example_method.__doc__)

输出

Example docstring. (additional content!)
Other docstring.

关于python - 根据类属性更 retrofit 饰器中类方法的文档字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47439594/

相关文章:

python - Sphinx - 找不到文件 - sys.path 问题

python - 如何在可重写的类方法上使用装饰器

python - Django Heroku 推送失败

python - 等待 asyncio.Future 引发 concurrent.futures._base.CancelledError 而不是等待设置值/异常

python - 合并两个字典列表并更新 key

python - Flask View 中装饰器的顺序是否重要?

python - 如何检查Python中的函数装饰器

python - 将 Pandas 列拆分为多列

html - 在 Sphinx 文档中添加垂直空间

python - .. 重组文本中的 plot 指令