Может ли лямбда или другой метод использоваться в качестве параметра по умолчанию в Python - PullRequest
0 голосов
/ 02 июня 2018

Я хотел бы использовать параметр по умолчанию, который инициализируется при вызове функции, поэтому каждый раз, когда вы вызываете ее, это другой параметр по умолчанию.Чтобы проиллюстрировать то, что я спрашиваю, скажем, вам нужна функция разности времени, которая по умолчанию установлена ​​на текущее время, если 2-й раз не указан:

обычно вы делаете что-то вроде этого.

def tdiff(target_time, curr_time=None):
   if curr_time == None:
      curr_time = datetime.datetime.now()
   return  curr_time - target_time

, нобыло бы лучше избавиться от оператора if.Можно ли это сделать с помощью лямбды?(Как-то так)

def tdiff(target_time,  curr_time= lambda : datetime.now() ): 
    return curr_time - target_time

Редактировать: я понимаю, лямбда не будет работать.Будет ли работать любой другой метод?

Ответы [ 3 ]

0 голосов
/ 02 июня 2018

Вы не можете, по довольно фундаментальной причине:

def f(arg=expression):

оценивает expression в то время, когда выполняется оператор def, а объект, для которого оценивается expression, сохраняется в объекте функциив качестве значения по умолчанию для локального имени arg.Когда тело функции будет выполнено, внутри тела arg будет просто извлечен объект expression, первоначально оцененный для.И ничего из этого не может быть изменено.

Так что, конечно, вы можете указать выражение lambda, но тогда arg будет привязано к объекту функции lambda выражение возвращается.Если вы хотите вызвать этот функциональный объект, вам нужно будет записать это как arg() в теле.Обычный arg просто получит объект функции.

0 голосов
/ 02 июня 2018

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

Я создал это, чтобы попробовать.

import datetime

class DefaultParams():
    @property
    def curr_time( self ):
        return datetime.datetime.now()

при доступе к свойству defaults.curr_time запустить его, он даеттекущее время без возможности вызова

>>> defaults = DefaultParams()
>>> defaults.curr_time
datetime.datetime(2018, 6, 2, 10, 49, 16, 38295)
>>> defaults.curr_time
datetime.datetime(2018, 6, 2, 10, 49, 17, 211985)

Так что я подключил это и распечатал curr_time при вызове tdiff

def tdiff(target_time,  curr_time= defaults.curr_time ): 
    print(curr_time)
    return curr_time - target_time

Но когда я запускаю, он показывает curr_time, развертывающий static @ 10: 48: 58.675151.

>>> tdiff(datetime.datetime.now())
2018-06-02 10:48:58.675151
datetime.timedelta(-1, 85430, 433255)
>>> tdiff(datetime.datetime.now())
2018-06-02 10:48:58.675151
datetime.timedelta(-1, 85429, 58707)

Так что это никак не может быть возможно.Я все еще думаю, что было бы полезно, чтобы Python мог делать такие вещи.

0 голосов
/ 02 июня 2018

Можно ли это сделать с помощью лямбды?

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

if callable(curr_time):
    curr_time = curr_time()

, но в этот момент вы могли бы также просто использовать if curr_time is None: подход, который вы включили в свой вопрос.

(Обратите внимание, что сравнение должнобыть сделанным как is None, а не == None.)

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