通常的属性访问方法要求属性名称是有效的python标识符.
但属性不必是有效的python标识符:
>>> class Thing:
... def __init__(self):
... setattr(self, '0potato', 123)
...
>>> t = Thing()
>>> Thing.__getattribute__(t, '0potato')
123
>>> getattr(t, '0potato')
123
Run Code Online (Sandbox Code Playgroud)
当然,t.0potato仍然是一个SyntaxError,但属性仍然存在:
>>> vars(t)
{'0potato': 123}
Run Code Online (Sandbox Code Playgroud)
这是允许的原因是什么?对于带有空格,空字符串,python保留关键字等的属性,是否真的有任何有效的用例?我认为原因是属性只是对象/命名空间dict中的键,但这没有意义,因为不允许使用其他有效dict键的对象:
>>> setattr(t, ('tuple',), 321)
TypeError: attribute name must be string, not 'tuple'
Run Code Online (Sandbox Code Playgroud) 以下是无效的Python:
def myInvalidFun(kw arg zero=6):
pass
Run Code Online (Sandbox Code Playgroud)
以下是有效的Python:
def myValidFun(**kwargs):
if kwargs.has_key("kw arg zero"):
pass
Run Code Online (Sandbox Code Playgroud)
myValidFun然而,打电话是很棘手的。例如,以下几种方法不起作用:
myValidFun(kw arg zero=6) # SyntaxError: invalid syntax
myValidFun("kw arg zero"=6) # SyntaxError: keyword can't be an expression
kwargs = dict("kw arg zero"=6) # SyntaxError: keyword can't be an expression
myValidFun(**kwargs)
Run Code Online (Sandbox Code Playgroud)
(也许与最后两个错误相同的错误暗示了幕后发生的情况?)但是,这确实有效:
kwargs = {"kw arg zero": 6}
myValidFun(**kwargs)
Run Code Online (Sandbox Code Playgroud)
myValidFun("kw arg zero"=6)鉴于创建字典的 {:} 语法,是否有特别无效的 原因?
(更多背景:我有一个很像字典的类,只是进行了大量的验证,并且__init__使用字典的条目构建一个容器,但不是字典......它实际上是一个 XML ElementTree,它在某些方面类似于列表,而在其他方面则类似于字典。该__init__方法必须采用“我的第一个元素”和“my_first_element”之类的键,并将它们视为不同的事物。类和__init__**kwargs 一起工作正常,但初始化我的类是我的示例形式的多行代码,它确实有效,而且似乎可以更简单。)
编辑:我理解标识符的概念,我的无效代码是为了说明这一点。我想我的问题应该改写为:
为什么以下内容有效?:
myValidFun(**{"invalid identifier":6})
Run Code Online (Sandbox Code Playgroud)