Why can a Python object have an attribute represen

2019-05-11 18:38发布

I think I might have a fundamental misunderstanding of what a python attribute actually is. Consider the following:

 >>> 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

Why does Python allow me to set an attribute if I can't legally access it with dot notation? I understand that t.0 makes no sense, but at the same time I wonder why it's no different than t.one because I created them the same way.

2条回答
Lonely孤独者°
2楼-- · 2019-05-11 19:30

Attributes are a kind of members any Python object can have. Usually you would expect the built-in syntax to dictate what kind of attribute names are accepted. For that, the definition is pretty clear:

attributeref ::=  primary "." identifier

So what follows after the dot is required to be a valid identifier which limits the allowed attribute names easily. Ignoring other Unicode areas for now, it essentially means that the attribute may not start with a number. So 0 is not a valid identifier and as such t.0 is not a valid attribute reference as per the specification.

However, getattr and alike work a bit differently. They just require the attribute name to be a string. And that string is passed on directly to the internal PyObject_GetAttr functions. And those don’t require a valid identifier.

So using getattr etc., you can essentially trick Python and attach attribute to objects, which names would not be allowed according to the specification of the language.

查看更多
放我归山
3楼-- · 2019-05-11 19:36

This is just a quirk of the syntax and semantics of python. Any string can be used as an attribute name, however only identifiers can be used with dot notation. Thus the only way of accessing non-identifier attributes is with getattr/setattr or some other indirect function. Strangely enough this practice doesn't extend so far as to allow any type to be an attribute, only strings get that privilege.

查看更多
登录 后发表回答