为什么Python对象可以有一个由整数表示的属性?
我想我可能对python属性实际上是什么有一个基本的误解。考虑以下事项:为什么Python对象可以有一个由整数表示的属性?,python,class,object,attributes,Python,Class,Object,Attributes,我想我可能对python属性实际上是什么有一个基本的误解。考虑以下事项: >>> class Test: ... pass ... >>> t = Test() >>> setattr(t, '0', 0) >>> t.0 File "<stdin>", line 1 t.0 ^ SyntaxError: invalid syntax >>>
>>> class Test:
... pass
...
>>> t = Test()
>>> setattr(t, '0', 0)
>>> t.0
File "<stdin>", line 1
t.0
^
SyntaxError: invalid syntax
>>> getattr(t, '0')
0
>>> setattr(t, 'one', 1)
>>> t.one
1
>>> getattr(t, 'one')
1
>类测试:
... 通过
...
>>>t=测试()
>>>setattr(t,'0',0)
>>>t.0
文件“”,第1行
t、 0
^
SyntaxError:无效语法
>>>getattr(t,'0')
0
>>>设置属性(t'一',1)
>>>t.1
1.
>>>getattr(t,‘一’)
1.
如果我不能合法地使用点符号访问属性,Python为什么允许我设置属性?我理解
t.0
毫无意义,但同时我想知道为什么它与t.one
没有什么不同,因为我是以同样的方式创建它们的。这只是python语法和语义的一个怪癖。任何字符串都可以用作属性名称,但是只有标识符可以与点表示法一起使用。因此,访问非标识符属性的唯一方法是使用getattr/setattr或其他一些间接函数。奇怪的是,这种做法并没有扩展到允许任何类型作为属性,只有字符串才能获得这种特权。属性是任何Python对象都可以拥有的一种成员。通常,您希望内置语法指示接受哪种类型的属性名。为此,定义为:
因此,点后面的内容需要是一个有效的,可以很容易地限制允许的属性名称。现在忽略其他Unicode区域,这本质上意味着该属性不能以数字开头。因此0
不是有效的标识符,因此t.0
不是规范中的有效属性引用
但是,getattr
和类似的函数的工作方式有点不同。它们只要求属性名为字符串。该字符串直接传递给内部函数。这些不需要有效的标识符
因此,使用
getattr
等,您基本上可以欺骗Python并将属性附加到对象,而根据语言的规范,这些对象的名称是不允许的。“奇怪的是,这种做法没有扩展到允许任何类型成为属性的程度,只有字符串才能获得这种特权”。这是正确的,但是您可以在\uuuu dict\uuu
中将任何哈希对象指定为键。标准库实际上在中使用了它。@dano取决于对象。插槽属性未存储在目录中。我还可以覆盖\uuuu getattribute\uuuu
来改变它。
attributeref ::= primary "." identifier