Что произойдет, если вы пишете имя переменной только в python?

Недавно мне стало любопытно, но что происходит в строке 2 следующего фальшивого кода на Python:

def my_fun(foo,bar):
    foo
    return foo + bar

Причина, по которой мне стало интересно, это то, что я пытаюсь использовать Light Table и пытаюсь поставить часы на "foo". Похоже, что интерпретатор python зависает.

Правильно ли я полагаю, что эта строка абсолютно не влияет и не вызывает какой-либо ошибки? Может ли кто-нибудь объяснить, что делает интерпретатор именно здесь?

Ответы

Ответ 1

Можно посмотреть, что происходит с небольшой помощью встроенного модуля dis:

import dis

def my_fun(foo,bar):
    foo
    return foo + bar

dis.dis(my_fun)

Функция dis.dis разбирает функции (yep, может разбираться сама), методы и классы.

Вывод dis.dis(my_fun):

  4           0 LOAD_FAST                0 (foo)
              3 POP_TOP

  5           4 LOAD_FAST                0 (foo)
              7 LOAD_FAST                1 (bar)
             10 BINARY_ADD
             11 RETURN_VALUE

Первые два байткода - это именно то, что нам нужно: строка foo.

Вот что делают эти байткоды:

  • Первая выводит ссылку на локальную переменную foo на стек (LOAD_FAST)
  • Второй удаляет верхнюю часть стека (POP_TOP)

В принципе, строка foo не действует. (ну, если переменная foo не определена, то LOAD_FAST будет бросать NameError)

Ответ 2

Ничего не происходит. Это становится эквивалентом бессмысленной операции Глядя на вывод dis

In [3]: dis.dis(my_fun)
  2           0 LOAD_FAST                0 (foo)
              3 POP_TOP             

  3           4 LOAD_FAST                0 (foo)
              7 LOAD_FAST                1 (bar)
             10 BINARY_ADD          
             11 RETURN_VALUE 

Мы видим, что он быстро загружается для foo, и ничего не делает с ним.

Ответ 3

Попробуйте в командной строке: он просто возвращает значение в foo. Это не значит, что в некоторых особых случаях он не может иметь побочных эффектов: если вы делаете что-то вроде:

def my_fun(foo, bar):
    foo.prop
    return foo.func(bar)

хотя технически мы только что вернули значение, если оно определено как свойство, тогда foo.prop может фактически вызвать функцию.

Но обычно... вы не делаете этого в модулях, только в интерактивной консоли.

Ответ 4

Оператор foo является примером выражения выражения , поэтому его оценивают, когда интерпретатор встречает его.

Оператор выражения оценивает список выражений (который может быть одно выражение).

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

Ответ 5

Ничего не происходит:

>>> def baz(foo, bar):
    foo
    return bar

>>> baz(10, 20)
20

Операция не действует.