![](/img/trans.png)
[英]How can I write a python function to accept *arguments and a keyword argument?
[英]python not accept keyword arguments
我试图使我的代码不接受关键字参数,就像一些bulitins也不接受关键字参数,但是,我无法这样做。 在这里,根据我的有限理解,我的想法是: -
def somefunc(a,b):
print a,b
somefunc(10,20)
输出:
10 20
现在,当我运行以下内容时(我知道这不是函数定义中的关键字参数,但是, 查看函数调用,它似乎与调用接受关键字参数的函数时的语法相同 ) :
somefunc(b=10,a=20)
输出:
20 10
我有两个问题 : -
somefunc(b=10,a=20)
而不是函数定义,这似乎是对一个只接受普通参数的函数的调用或接受关键字参数的函数。 口译员如何区分两者? 为什么我要这样做呢? 我只是在检查我是否可以这样做,所以我不会错过任何深入理解python的东西。 我知道python是否允许这样做。
您可以使用任意参数列表来执行此操作。 请参阅http://docs.python.org/tutorial/controlflow.html#arbitrary-argument-lists
例如:
def somefunc(*args):
print args[0], args[1]
没有关键字的电话:
somefunc(10,20)
得到:
10 20
使用关键字调用:
somefunc(a=10,b=20)
给出错误:
TypeError: someFunc() got an unexpected keyword argument 'a'
目前还不清楚你为什么要这样做。
ad 1)正确的名称由Python自动验证,如果它们被称为somefunct(name=value, ...)
。 我不需要记住参数的确切标准顺序,并通过每次使用时每月查看文档来验证它太“神经质”,如果我记得一个具有良好描述性参数名称的函数,它将被测试它们被接受通过Python。 相反,使用参数的正确顺序只能通过文档验证。 通过命名参数调用优先于非常长的位置参数列表。 因此,报告的行为是有根据的。 (简短的单字母参数“a,b”当然不能帮助解决错误。)
ad 2)一些众所周知的内置快速函数用C语言编写,具有少量固定数量的必需参数,不支持使用命名参数调用。 (例如hasattr
)
这是因为它们只使用简单的标题...(... PyObject *args)
,因此所有命名的参数都会被自动拒绝。 (Python无法反省C源代码中的参数名称。:-)
许多其他C函数都有一个标题...(... PyObject *args, PyObject *kwds)
,它们通过实现更复杂的验证PyArg_ParseTupleAndKeywords
并将名称写入docs字符串,明确地支持名称的精确列表。
编辑:改进英语
查看函数调用somefunc(b = 10,a = 20)而不是函数定义,这似乎是对只接受普通参数的函数的调用或接受关键字参数的函数。 口译员如何区分两者?
不确定这是否是你所要求的,但如果我理解你的话,那么答案是“它没有”。 无论函数中如何定义参数,都可以使用关键字调用函数。 如果使用关键字语法传递任何参数(例如, f(a=...)
),Python会将相应的值绑定到函数定义中具有相同名称的参数。 是否定义了默认值无关紧要。 这两种函数定义不会创建不同的“种类”参数,只是某些参数可能具有默认值而其他参数可能没有。 因此,无论你做def f(a)
还是def f(a=2)
,你仍然可以做f(a=...)
。 唯一的限制是你必须首先传递/定义位置参数(例如,你不能做def f(a=2, b)
或f(a=2, 3)
)。 另见这个答案 。
至于你问题的第二部分,我不知道有什么方法可以阻止Python函数接受命名参数的关键字传递值。 如果仅定义*args
则它将不接受关键字参数,但位置参数不能具有单独的名称。
Python中关键字和位置参数之间没有如此强烈的区别。 事实上,它很简单:
位置参数按照它们在函数调用中列出的顺序进行解析。关键字参数可以按任何顺序添加,但不能在位置参数之前添加 。
所以,如果你有这个:
def foo(x):
pass
你可以做:
foo(1) # positional
foo(x=1) # keyword
但你不能做foo()
因为你没有提供默认值。
同样,如果你有这个:
def foo(x,y='hello'):
pass
foo(1) # this works fine
foo() # this is invalid, as an argument without a default isn't passed
foo(y='hello',1) # error - positional arguments come before keyword arguments
不要忘记阅读任意参数列表 。
我认为这是一个非常糟糕的Python功能,并且可能导致非常难以维护和错误的代码。 假设你有一个功能:
def myurl(x, y):
url = "{}:{}".format(x, y)
return url
尽管使用关键字参数替换位置似乎是个好主意但是不要这样做。 我很惊讶没有Python选项会阻止使用关键字参数调用此函数:
>> print myurl(x="localhost", y=8080)
如果有人认为图书馆的可读性更高,如果写成:
def myurl(hostname, port):
url = "{}:{}".format(hostname, port)
return url
然后使用关键字调用为myurl(x="localhost", y=8080)
的其余代码将失败:
TypeError: myurl() got an unexpected keyword argument 'x'
这意味着你的本地函数变量突然变成了一个全局变量! 我希望在Python 3中以某种方式解决这个问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.