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

Определите, был ли именованный параметр передан

Я хотел бы знать, можно ли определить, был ли передан параметр функции со значением по умолчанию в Python. Например, как работает dict.pop?

>>> {}.pop('test')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'pop(): dictionary is empty'
>>> {}.pop('test',None)
>>> {}.pop('test',3)
3
>>> {}.pop('test',NotImplemented)
NotImplemented

Как метод pop определяет, что первый раз возвращаемое значение по умолчанию не было передано? Это что-то, что можно сделать только в C?

Спасибо

4b9b3361

Ответ 1

Я думаю, вы имеете в виду "аргумент ключевого слова", когда вы говорите "именованный параметр". dict.pop() не принимает аргумент ключевых слов, так что эта часть вопроса является спорной.

>>> {}.pop('test', d=None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pop() takes no keyword arguments

Тем не менее, способ определить, был ли предоставлен аргумент, - использовать синтаксис *args или **kwargs. Например:

def foo(first, *rest):
    if len(rest) > 1:
        raise TypeError("foo() expected at most 2 arguments, got %d"
                        % (len(rest) + 1))
    print 'first =', first
    if rest:
        print 'second =', rest[0]

При некоторой работе и использовании синтаксиса **kwargs можно полностью эмулировать соглашение о вызове python, где аргументы могут быть предоставлены положением или по имени, а аргументы, предоставленные несколько раз (по положению и имени), ошибка.

Ответ 2

Соглашение часто использует arg=None и использует

def foo(arg=None):
    if arg is None:
        arg = "default value"
        # other stuff
    # ...

чтобы проверить, было ли оно передано или нет. Разрешить пользователю передавать None, который будет интерпретироваться так, как будто аргумент не был передан.

Ответ 3

Вы можете сделать это следующим образом:

def isdefarg(*args):
    if len(args) > 0:
        print len(args), "arguments"
    else:
        print "no arguments"

isdefarg()
isdefarg(None)
isdefarg(5, 7)

Подробную информацию см. в документации Python на calls.

Ответ 4

def f(one, two=2):
   print "I wonder if", two, "has been passed or not..."

f(1, 2)

Если это точный смысл вашего вопроса, я думаю, что нет никакого способа отличить 2, который был в значении по умолчанию, и 2, который был передан. Я не нашел, как выполнить такое различие даже в inspect.

Ответ 5

Я не уверен, полностью ли я понимаю, чего вы хотите; Однако:

def fun(arg=Ellipsis):
    if arg is Ellipsis:
        print "No arg provided"
    else:
        print "arg provided:", repr(arg)

делает то, что вы хотите? Если нет, то, как предложили другие, вы должны объявить свою функцию синтаксисом *args, **kwargs и проверить в kwargs dict для существования параметра.