Голая звездочка в аргументах функции?
Что делает голая звездочка в аргументах функции?
Когда я посмотрел на модуль рассола, я увидел это:
pickle.dump(obj, file, protocol=None, *, fix_imports=True)
Я знаю об одинарных и двойных звездочках, предшествующих аргументам (для переменного числа аргументов), но это ничего не предшествует. И я уверен, что это не имеет никакого отношения к рассолу. Это, вероятно, просто пример этого происходит. Я узнал его имя только когда отправил это переводчику:
>>> def func(*):
... pass
...
File "<stdin>", line 1
SyntaxError: named arguments must follow bare *
Если это имеет значение, я на Python 3.3.0.
Ответы
Ответ 1
Bare *
используется, чтобы заставить вызывающего пользователя использовать именованные аргументы - поэтому вы не можете определить функцию с *
в качестве аргумента, если у вас нет следующих аргументов ключевого слова.
Подробнее см. этот ответ или документацию Python 3.
Ответ 2
В то время как исходный ответ полностью отвечает на вопрос, просто добавляя немного соответствующей информации. Поведение для одиночной звездочки происходит от PEP-3102
. Цитирование связанного раздела:
The second syntactical change is to allow the argument name to
be omitted for a varargs argument. The meaning of this is to
allow for keyword-only arguments for functions that would not
otherwise take a varargs argument:
def compare(a, b, *, key=None):
...
В простом английском языке это означает, что для передачи значения для ключа вам необходимо явно передать его как key="value"
.
Ответ 3
def func(*, a, b):
print(a)
print(b)
func("gg") # TypeError: func() takes 0 positional arguments but 1 was given
func(a="gg") # TypeError: func() missing 1 required keyword-only argument: 'b'
func(a="aa", b="bb", c="cc") # TypeError: func() got an unexpected keyword argument 'c'
func(a="aa", b="bb", "cc") # SyntaxError: positional argument follows keyword argument
func(a="aa", b="bb") # aa, bb
приведенный выше пример с ** kwargs
def func(*, a, b, **kwargs):
print(a)
print(b)
print(kwargs)
func(a="aa",b="bb", c="cc") # aa, bb, {'c': 'cc'}
Ответ 4
Я нашел очень полезной следующую ссылку, объясняющую *
, *args
и **kwargs
:
https://pythontips.com/2013/08/04/args-and-kwargs-in-python-explained/
По сути, в дополнение к ответам выше, я узнал с сайта выше (кредит: https://pythontips.com/author/yasoob008/) следующее:
С демонстрационной функцией, определенной сначала ниже, есть два примера, один с *args
и один с **kwargs
def test_args_kwargs(arg1, arg2, arg3):
print "arg1:", arg1
print "arg2:", arg2
print "arg3:", arg3
# first with *args
>>> args = ("two", 3,5)
>>> test_args_kwargs(*args)
arg1: two
arg2: 3
arg3: 5
# now with **kwargs:
>>> kwargs = {"arg3": 3, "arg2": "two","arg1":5}
>>> test_args_kwargs(**kwargs)
arg1: 5
arg2: two
arg3: 3
Таким образом, *args
позволяет вам динамически создавать список аргументов, которые будут приниматься в порядке их подачи, тогда как **kwargs
может **kwargs
передачу аргументов NAMED и может обрабатываться NAME соответственно (независимо от порядка в которым их кормят).
Сайт продолжает, отмечая, что правильный порядок аргументов должен быть:
some_func(fargs,*args,**kwargs)