Почему foo = function () запускает функцию в Python? - PullRequest
7 голосов
/ 11 марта 2012

Я дошёл до Упражнения 41 в Изучить Python на нелегком пути, и мне действительно тяжело сосредоточиться на том факте, что все это зависит от функции, выполняемой только потому, что она была назначена в качестве значения для Переменная. Я написал небольшой скрипт, чтобы подтвердить, что так оно и есть:

def pants():
    print "Put on some pants!"

def shorts():
    print "And don't forget your underwear!"

zap = pants()
thing = shorts()

С результатами:

Put on some pants!
And don't forget your underwear! 

Очевидно, что это происходит, но я не могу понять, почему язык работает таким образом - какая логика стоит за языком, который делает это ценным способом работы. Я думаю, что было бы полезно для меня продвинуться вперед, чтобы понять , почему это так, а не просто "это так работает".

Для ясности: я спрашиваю (наверное), почему функция работает, когда все, что я делаю, это назначаю ее как значение для чего-то. Операторы печати как раз там, так что я вижу, что функция действительно работает.

Это факт, что я на самом деле не бегаю

брюки () шорты ()

что меня смущает.

Если провести аналогию с пытками, если бы я-печеньки-печенья-дома были "печеньками"), а я должен был делать печенья по субботам, я мог бы в конечном итоге поверить, что

Суббота = печенье ()

но просто думать «эй, суббота - день печенья» - это не то же самое, что на самом деле выпечка печенья ... так почему просто сказать

Суббота = печенье ()

на самом деле испечь куки, а не просто настроить субботу с переменной "cookies ()" для дальнейшего использования?

Ответы [ 7 ]

16 голосов
/ 11 марта 2012

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

Пример:

def pants():
    print "Put on some pants!"

def shorts():
    print "And don't forget your underwear!"

zap = pants
thing = shorts

А потом, когда вы хотите вызвать эти функции:

zap()
thing()
6 голосов
/ 11 марта 2012

Итак, очевидно, что это происходит, но я не могу понять, почему язык работает таким образом - какая логика стоит за языком, который делает это ценным способом работы. Я думаю, для меня было бы полезно понять, почему это так, а не просто «так оно и работает».

Языку нужен какой-то способ различения функции и акта вызова функции. Вот что дают круглые скобки.

f = foo

Теперь f привязан к самой функции. Функция foo может быть выполнена с помощью f().

f = foo()

Это вызывает функцию foo и связывает возвращаемое значение с f.

Обратите внимание, что привязывать возвращаемое значение к имени или нет, не имеет значения. Просто пишу

foo()

также выполнит функцию, но возвращаемое значение будет просто проигнорировано.

5 голосов
/ 11 марта 2012

Хотя может показаться, что ваши функции ничего не возвращают, на самом деле они возвращают. Цитирование документации Python.org :

Оператор return возвращает значение из функции. return без выражения аргумент возвращает None. Падение с конца функции также возвращает None.

Итак, ваши функции действительно выглядят так:

def pants():
    print "Put on some pants!"
    return None

def shorts():
    print "And don't forget your underwear!"
    return None

Ваши назначения присваивают zap, что pants возвращает (т.е. значение pants()), и thing, что shorts возвращает. В вашем случае оба None, но, конечно, функции должны быть запущены, чтобы понять это (*). В конце концов, это может быть то, что pants возвращает 42 в течение високосных лет, и что shorts возвращает 'Foobar' всякий раз, когда какой-то генератор случайных чисел "катит" 6.


(*) Отступление: То, что функции «должны быть запущены», не должно считаться универсально верным. В чистом значении и без учета специфики Python (о которой я знаю очень мало), компилятор может понять, что обе функции идентичны None и не вызывать никаких вызовов при выполнении программы это запустить. Но функция, которая печатает что-то (или проверяет, является ли текущий год високосным, или бросает кубик), не будет чистой.

2 голосов
/ 11 марта 2012

zap = pants() свяжет возвращаемое значение функции с переменной, поэтому, конечно, функция запускается, если вы свяжете ее с переменной.

def foo():
    return 1

var = foo()
print var

выведет 1.

Надеюсь, это поможет.

Редактировать: Если вы ожидаете, что значение переменной будет "надето на штаны", вы действительно путаете print и return, как указывали людив комментариях.

1 голос
/ 11 марта 2012

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

То, что вы делаете там, говорит: «присвойте результат этих функций этим переменным».

Но поскольку вы не возвращаете никаких значений из этих функций, вы ничего не видите в переменных.

Однако, поскольку у вас есть оператор print, вы видите, что интерпретатор выполняет эти функции, когда он пытается присвоить переменную результатам этой функции.

0 голосов
/ 11 марта 2012

Из вашего вопроса, что я думаю, что вы хотите, zap будет иметь значение "Put on some pants!", а thing будет иметь значение "And don't forget your underwear!". Если это ваша проблема, давайте обсудим это. В противном случае вам не нужно читать дальше, как я только что говорил обо всем этом.

Давай повеселимся. Когда вы определяете функцию, вы похожи на создание машины, которая делает то, что вы от нее хотите. Теперь давайте подумаем о машине, которая, когда вы даете ей немного еды, она их рубит и ... ничего не делает! Я имею в виду, что я сделал эту машину для измельчения продуктов и ничего больше! Вы не получите обратно свою нарезанную пищу, но на самом деле она нарезала вашу еду, как вы ее приготовили.

Теперь, когда вы хотите вернуть свою нарезанную пищу, вы создаете другую машину, которая забирает ваши продукты, измельчает их и возвращает вам. Плодотворная машина, не правда ли? ; -)

Все они верны для функций в программировании или математике (хотя я не знаю ни одной void-функции в математике!: P). Когда вы создаете функцию, вы должны указать ей, просто ли она выполняет какую-то работу или она выполняет некоторую работу, и вернуть результат . Способ сообщить функции - оператор return. В своих функциях вы только что сказали что-то делать. И это print "......" так же, как и функции. Вы вызываете with () в конце, и он выполняет свою работу, он печатает его. Но, как я сказал, если вы не скажете, чтобы он вернул результат, это не так. И поскольку он не возвращает никакого результата, переменной не будет присвоено ничего (не путайте его с None). Когда вы написали эти строки (если в интерпретаторе) или запустили скрипт, вы увидите, что эти строки напечатаны, но ваши zap и thing не имеют значений.

Так как это исправить? Скажите им, чтобы вернуть строки для переменных. Чтобы сказать, что функции делают это, замените операторы print на операторы return. И неважно экспериментировать с тем, что вы знаете, знать, что вы знаете о своих знаниях, это правда: -)

Надеюсь, это поможет: -)

0 голосов
/ 11 марта 2012

Ваши функции вызываются из-за круглых скобок после имени:

zap = pants()

Это вызывает функцию брюк и помещает результат в zap. Если вы сделали это вместо:

zap = pants

тогда zap теперь относится к самой функции штанов.

А если вы только что написали

pants()

тогда будет вызвана функция брюк, но результат (которого нет) никогда не будет помещен в переменную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...