Подтвердить что ты не робот

Python: почему `return` не разрешен в модуле

Если вы посмотрите на байт-код Python, скомпилированный из модулей, вы увидите в конце:

10 LOAD_CONST               0 (None)
13 RETURN_VALUE        

т.е. a return отлично действует на корневом уровне модуля. Однако, если вы попытаетесь использовать его в исходном коде, вы получите:

SyntaxError: 'return' outside function

Почему?


Это, конечно, решение для языкового дизайна. Но почему это было сделано? A return часто весьма полезен в модуле. Например. Я иногда хочу написать этот код в начале модуля:

import sys
if sys.platform != "linux2":
    print "your platform is not yet supported"
    # define some stubs
    def foo(): pass
    def bar(): pass
    return

И я не хочу создавать там исключение (потому что это приведет к тому, что модуль не будет загружаться, который я не хочу).


Собственно, я взломал некоторый код вместе, который может управлять байт-кодом Python "на лету" и просто сделать возврат (или в моем случае перейти к концу, где выполняется возврат). Это работает. Единственная причина, по которой это только CPython, заключается в том, что нет стандартного способа манипулирования объектом кода.

Здесь - это код.


Для возможных ответов: я бы предпочел настоящие доказательства, некоторые прошлые высказывания Гвидо ван Россума или около того об этом, а не только о какой-либо случайной дискуссии. Я, конечно, могу использовать оба преимущества (как уже было сказано) и недостатки, но на самом деле я не вижу большой причины против этого.

4b9b3361

Ответ 1

Я бы предположил, что это решение со стороны разработчиков python, поскольку оно вынуждает пользователя модуля учитывать тот факт, что их система не поддерживается (вместо того, чтобы получать разработчики модуля догадываются, что должно произойти). Представьте себе их удивление, когда они запускают код на машине для Windows, и внезапно module.foo() работает не так, как ожидалось. (Ваше предупреждение print может быть полностью захоронено во всех видах других мусора, которые могут быть сброшены на стандартный вывод).

Я думаю, что самый идеальный способ справиться с этим - поднять ImportError или NotImplementedError. Тогда пользователь может решить, смогут ли они жить без этого модуля и продолжать (за исключением исключения), или если их программа должна сработать и сжечь там.

Ответ 2

Это не "почему" (я подозреваю, что ответом на этот вопрос является просто "return принадлежит функции, и нет никаких веских причин для ее включения в код модуля верхнего уровня"). Но это аккуратный обходной путь, о котором вы можете не знать. Ваш код может быть переработан следующим образом без особых сложностей:

import sys

def main():
    global foo, bar
    if sys.platform != "linux2":
        print "your platform is not yet supported"
        # define some stubs
        def foo(): pass
        def bar(): pass
        return

main()