2016-05-31 5 views
2

Когда я создаю класс с методом, как это:Python строки документации неожиданно None

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

, кажется, не в состоянии, так как это строка документации 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

Wow: на моей локальной машине все они выводят ожидаемые docstrings ('sys.version == '3.4.3+ (по умолчанию, 14 октября 2015, 16:03:50) \ n [GCC 5.2.1 20151010]' ') – Herbert

+1

Работает на моей машине, это может быть ошибка с ideone. –

+0

Кроме того: я видел то же поведение '__doc__', которое было' None' на моей машине для менее минимальных примеров (код кода клиента). – Herbert

ответ

2

Update: основе @user2357112's suggestion, я нашел способ воспроизвести поведение ideone в местном интерпретатором, и это, вероятно, причиной странных несоответствий. В частности, похоже, что ideone запускает сценарий оболочки в Python без флага -OO, но с использованием the compile builtin function для компиляции предоставленного пользователем кода с optimize=2 в качестве аргумента, то eval в результате скомпилированного объекта кода. Похоже, что это приводит к упомянутому выше разложению; sys.flags.optimize - 0 и __debug__ - True (соответствует состоянию внешнего интерпретатора), но docstrings и 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__1010 s как True, но проверяет как False), в то время как снятие докстеров и assert s полностью завершается во время компиляции (поэтому они отражают состояние compileoptimize).


Старый ответ, который применяется чаще вне ideone:

В случаях, не ideone, поведение, как это будет означать, что вы бежите с переключателем -OO (двойной оптимизировано). При запуске с -OO, docstrings are stripped during byte code compilation, replaced with None; значение PYTHONOPTIMIZE переменная окружения 2 будет иметь тот же эффект.

+1

Но флаг 'optimize' установлен на 0 http://ideone.com/Zq9TdR – vaultah

+0

@vaultah: С другой стороны, если вы намеренно загрузите Ideone синтаксическую ошибку, [traceback] (http://ideone.com)/BD67QR), который вы получаете, поступает из модуля 'py_compile', а не из-за регулярной синтаксической ошибки Python. Кажется, что он выполняет отдельные шаги компиляции и выполнения. 'py_compile' [defaults] (https://docs.python.org/3/library/py_compile.html) для компиляции кода на том же уровне оптимизации, что и текущий интерпретатор. – user2357112

+0

Я подозреваю, что ребята Ideone установили, что Python запускается на '-OO' для прохода компиляции, не понимая, что скомпилированный код наследует этот параметр' -OO', даже если '-OO' не указан для прогона выполнения. – user2357112

Смежные вопросы