alist = []
def show(*args, **kwargs):
alist.append(*args, **kwargs)
print(alist)
>>> show('tiger')
['tiger']
>>> show('tiger','cat')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in show
TypeError: append() takes exactly one argument (2 given)
>>> show('tiger','cat', {'name':'tom'})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in show
TypeError: append() takes exactly one argument (3 given)
由于alist的方法append只接受一个参数,为什么不在方法show的定义中检测行alist.append(*args, **kwargs)
上的语法错误?
答案 0 :(得分:2)
这不是语法错误,因为语法非常精细,并且该函数可能会也可能不会引发错误,具体取决于您调用它的方式。
你打电话的方式:
alist = []
def show(*args, **kwargs):
alist.append(*args, **kwargs)
print(alist)
>>> show('tiger')
['tiger']
>>> show('tiger','cat')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in show
TypeError: append() takes exactly one argument (2 given)
另一种方式:
alist = []
def show(*args, **kwargs):
alist.append(*args, **kwargs)
print(alist)
>>> show('tiger')
['tiger', 'tiger']
>>> class L: pass
...
>>> alist = L()
>>> alist.append = print
>>> show('tiger','cat')
tiger cat
<__main__.L object at 0x000000A45DBCC048>
答案 1 :(得分:1)
Python对象是强类型的。绑定到它们的名称不是。函数参数也不是。鉴于Python的动态特性,静态预测给定源位置的变量在执行时的类型是非常困难的,因此一般规则是Python不会费心去尝试。
在您的具体示例中,alist
不在本地范围内。因此,可以在执行函数定义后修改,并且您的函数可以看到更改,参见下面的代码片段。
因此,符合一般规则:当您致电alist
时,预测.append
是否会成为一个列表?几乎不可能。特别是,解释器无法预测这将是一个错误。
以下是一些代码,只是为了推动归属,即在Python中实现静态类型检查是不可能的。它使用非局部变量,如您的示例所示。
funcs = []
for a in [1, "x", [2]]:
def b():
def f():
print(a)
return f
funcs.append(b())
for f in funcs:
f()
输出:
[2] # value of a at definition time (of f): 1
[2] # value of a at definition time (of f): 'x'
[2] # value of a at definition time (of f): [2]
同样对于非全局非局部变量:
funcs = []
for a in [1, "x", [2]]:
def b(a):
def f():
print(a)
a = a+a
return f
funcs.append(b(a))
for f in funcs:
f()
输出:
2 # value of a at definition time (of f): 1
xx # value of a at definition time (of f): 'x'
[2, 2] # value of a at definition time (of f): [2]
答案 2 :(得分:0)
这不是语法错误,因为它是在运行时解决的。在解析期间最初会捕获语法错误。像无法匹配的括号,未定义的变量名,缺少参数(这不是缺少的参数* args意味着任意数量的参数)。
show
无法知道您在运行时传递的内容,因为您在args
内扩展show
变量,可能会有任意数量的参数进入这是有效的语法! list.append
有一个论点!一个tuple
,一个list
,一个int
,字符串,自定义类等等。您传递的是输入中的一些数字元素取决于。如果您移除*
它的所有花花公子就像其一个元素一样alist.append(args)
。
这一切都意味着您的show
功能有问题。它只能在长度为1时处理args
。如果它为0,则在append
处调用TypeError也会被调用。如果它超过它的破坏,但你不会知道,直到你用坏输入运行它。
您可以遍历args
(和kwargs
)中的元素并逐个添加。
alist = []
def show(*args, **kwargs):
for a in args:
alist.append(a)
for kv in kwargs.items():
alist.append(kv)
print(alist)