当我用这样的方法创建一个类时:
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
答案 0 :(得分:2)
更新:基于@user2357112's suggestion,我找到了一种在本地翻译中重现意外行为的方法,这可能是导致奇怪差异的原因。具体来说,看起来ideone正在Python 中运行包装脚本而没有 -OO
标志,但使用the compile
builtin function编译用户提供的代码optimize=2
作为参数,然后eval
生成的编译代码对象。看起来这会导致前面提到的拆分行为; sys.flags.optimize
为0
,__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
会产生相同的效果。