Python – сохранить функцию в переменной

У меня есть концепция, в которой я храню функцию в переменных, что облегчает мне задачу. Но у меня проблема в том, что значение переменной не вызывает функцию каждый раз динамически. Таким образом, он всегда возвращает одно и то же значение. Просто чтобы прояснить проблему, я сделал фрагмент кода, чтобы проиллюстрировать ее простым способом:

def value():
        resp = requests.get('http://www.google.com').elapsed.total_seconds()
        return resp

test = value()

while True:
        print test
        time.sleep(10)

Выход:

0.00649
0.00649

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


person Community    schedule 11.03.2016    source источник
comment
просто измените test = value() на test = value   -  person MaxU    schedule 11.03.2016
comment
@MaxU: здесь задействовано немного больше. Затем он напечатает что-то вроде <function value at 0x63f53e>   -  person zondo    schedule 11.03.2016
comment
@zondo, это был просто намек (а не полный ответ), так что это дает OP шанс понять, как с этим справиться.   -  person MaxU    schedule 11.03.2016


Ответы (4)


Предыдущие ответы верны, но, пожалуйста, позвольте мне уточнить.

В мире Python вещи имеют очень точное значение, но не всегда ясно, что к чему, если вы только начинаете.

Выражения — это вещи, которые имеют значение, и они включают такие вещи, как 123, some_variable и 10 / 2. Имя some_variable называется идентификатором просто потому, что оно идентифицирует значение. Так же, как имя Scruffy может идентифицировать вашу собаку.

Утверждения — это вещи, которые влияют на ход программы или состояние вашей программы, но не имеют значения. Ниже приведены примеры утверждений:

if x > 10:
    x -= 1

А также

def foo(x):
    print("The value of x is", x)

В отличие, например, от JavaScript, где почти все является выражением (и имеет значение), вы не можете сделать следующее:

my_function = def foo(x): print("The value of x is", x)

Предыдущий оператор def создаст функцию с именем foo, но сам оператор не имеет значения. Однако имя foo будет ссылаться на значение. Это означает, что когда вы пишете foo, значением будет вещь, а эта вещь — функция!

С другой стороны, выражение x() будет делать две вещи. Сначала он ищет значение идентификатора x. Надеюсь, это значение является функцией. После этого скобки означают, что значение будет вызвано. Что произойдет, если x не будет функцией?

>>> x = 10
>>> x()
Traceback (most recent call last):
  File "<ipython-input-3-7354d77c61ac>", line 1, in <module>
    x()
TypeError: 'int' object is not callable

Большая грубая ошибка: 10 не является «коллируемым». Вызываемый означает то, что можно вызвать как функцию.

Скобки, как вы, наверное, знаете, представляют собой список аргументов. В этом случае список просто пуст, поэтому, когда вы пишете x(), вы говорите: «вызовите то, на что ссылается имя «x», но не отправляйте никаких аргументов».

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

Чтобы ответить на ваш вопрос, наконец, давайте поиграем в игру замены. Правила просты, любое выражение можно заменить его значением:

def value():
    resp = requests.get('http://www.google.com').elapsed.total_seconds()
    return resp

Это оператор, поэтому он не имеет значения. Однако создается функция с именем value.

Функция состоит из двух операторов (опять же без значения), присваивания переменной и оператора возврата.

Однако то, что находится справа от =, является выражением. Короткий рассказ:

  • requests относится к модулю запросов
  • get относится к глобальной функции модуля в вышеуказанном модуле.
  • get('...') вызывает эту функцию, и что-то возвращается.
  • «Что-то» имеет свойство под названием elapsed, которое имеет свойство под названием total_seconds.
  • total_seconds — это идентификатор, который относится к вызываемому объекту. Вызываемый объект вызывается без каких-либо аргументов (total_seconds()) и что-то возвращается. Вероятно, число, судя по имени. Скажем, для простоты его значение всегда равно 10.

Следующим оператором является другое присваивание:

test = value()

Это можно рассматривать как «пусть имя« тест »относится к значению, возвращаемому вызываемым объектом, идентифицированным именем« значение », когда он вызывается с пустым списком аргументов». В нашем случае будет вызван функциональный объект с именем value, resp будет присвоено значение 10, затем оператор return сообщит вызывающей стороне, что этот вызов отправляет значение 10 обратно. Имя test с этого момента будет ссылаться на значение 10.

Давайте быстро пройдемся по циклу:

while True:
    print test
    time.sleep(10)

Делайте следующее до конца Времени:

  • print (оператор в Python 2, выражение в Python 3!) имеет побочный эффект вывода данных на экран. В противном случае это мало что дает.
  • Материалом в данном случае является любое значение выражения test. Мы уже знаем, что идентификатор test относится к значению 10. Он просто выведет «10» на экран.
  • Поспите десять секунд.
  • Повторение.

Вы, вероятно, захотите вызывать какую-то функцию на каждой итерации цикла («вызов» в основном означает «вызов» на латыни, мне нравятся причудливые слова). В противном случае программа будет просто печатать «10», «10», «10» снова и снова. Чтобы исправить это, вам сначала нужно изменить выражение, оцениваемое как часть оператора print, с простого идентификатора (test) на вызов функции:

print test()

Но это вызовет, как мы видели ранее, Big Fat Error, поскольку 10 не является вызываемой функцией. Чтобы исправить это (это то, что делают программисты, верно?) вам также нужно изменить значение test с 10, так как это не вызываемое, на функцию. На функцию можно ссылаться просто по ее имени, поэтому просто измените эту строку:

test = value()  # equals ten

К этому:

test = value  # equals the function called "value"

Функция теперь имеет два имени: старое имя «значение» и новое имя «тест». Каждый шаг в цикле будет запрашивать страницу снова и возвращать новое время, затраченное на выполнение запроса. Если запрос истечет, у вас будет другой вид сбоя, но это уже другая история.

Дополнительную информацию можно найти в Справочнике по языку Python.

person André Laszlo    schedule 11.03.2016

test = value() хранит не функцию, а результаты. Вы должны просто вызвать value() в своем цикле или, если вы хотите назначить функцию, это будет test = value, а затем test() в вашем цикле.

person AlG    schedule 11.03.2016

test = value() вызывает функцию и сохраняет возвращаемое значение. Функция не сохраняется. test = value сохранит функцию, но вам нужно print test() ее вызвать.

def value():
        resp = requests.get('http://www.google.com').elapsed.total_seconds()
        return resp

test = value

while True:
        print test()
        time.sleep(10)
person cdarke    schedule 11.03.2016

Вы можете изменить свой код следующим образом.

def value():
    resp = requests.get('http://www.google.com').elapsed.total_seconds()
    return resp

test = value()

while True:
    print test
    time.sleep(10)

изменить эту строку

тест = значение

to

тест = значение ()

Теперь означает, что вы сохраняете свою функцию в переменной.

person Saqib    schedule 05.05.2021