Python文档字符串出乎意料地为None

时间:2016-05-31 16:54:04

标签: python python-3.x python-3.4 docstring

当我用这样的方法创建一个类时:

class Foo:
    """ A class """
    def bar():
        " Hello world "
        pass

我希望__doc__返回方法的第一个语句,因为两个都是字符串。不幸的是,这不会发生:

print(Foo.__doc__)
print(Foo().__doc__)
print(Foo.bar.__doc__)
print(Foo().bar.__doc__)

输出None 4次。也是这里的例子

https://docs.python.org/3.4/library/functools.html?highlight=doc#functools.wraps

似乎失败了,因为docstring对我来说是None

from functools import wraps
def my_decorator(f):
    @wraps(f)
    def wrapper(*args, **kwds):
        print('Calling decorated function')
        return f(*args, **kwds)
    return wrapper

@my_decorator
def example():
    """Docstring"""
    print('Called example function')
print(example.__doc__)

还会打印None

为什么__doc__没有设置为指定的字符串?

ideone snipplet:http://ideone.com/cZNUQe

1 个答案:

答案 0 :(得分:2)

更新:基于@user2357112's suggestion,我找到了一种在本地翻译中重现意外行为的方法,这可能是导致奇怪差异的原因。具体来说,看起来ideone正在Python 中运行包装脚本而没有 -OO标志,但使用the compile builtin function编译用户提供的代码optimize=2作为参数,然后eval生成的编译代码对象。看起来这会导致前面提到的拆分行为; sys.flags.optimize0__debug__True(与外部解释器的状态匹配),但文档字符串和assert语句被剥离(与优化级别匹配)在调用compile时使用。

要重现,请使用Python运行以下脚本,而不传递-OO标志:

source = '''import sys
print(sys.flags)
print("Debug:", __debug__)
if __debug__:
    print("Debug")
else:
    print("Non-debug")
class Foo:
    """abc"""
print("Foo docstring:", Foo.__doc__)
assert True == False
'''

compiled = compile(source, '<test>', 'exec', optimize=2)
eval(compiled)

输出结果为:

sys.flags(debug=0, inspect=0, interactive=0, optimize=0, dont_write_bytecode=0, no_user_site=0, no_site=0, ignore_environment=0, verbose=0, bytes_warning=0, quiet=0, hash_randomization=1, isolated=0)
Debug: True
Non-debug
Foo docstring: None

其中前两行的行为就像没有-OO一样运行,而接下来的两行(并且没有AssertionError)表现得好像-OO有效。看起来sys.flags检查在运行时执行(这意味着它们反映了主解释器状态),__debug__是一半(if检查,并且可能在编译时执行其他条件逻辑,其他用法是运行时,请注意__debug__ print如何True,但测试为False),同时剥离文档字符串和assert s完全完成在编译期间(因此它们反映了compile&#39; optimize标志的状态。

旧答案更常适用于ideone

对于非意外情况,此类行为表示您正在使用-OO开关运行(双重优化)。与-OO, docstrings are stripped during byte code compilation, replaced with None一起运行时;将PYTHONOPTIMIZE环境变量设置为2会产生相同的效果。