非';t有效的python标识符

非';t有效的python标识符,python,attributes,Python,Attributes,通常的属性访问方法要求属性名为 但属性不必是有效的python标识符: >>> class Thing: ... def __init__(self): ... setattr(self, '0potato', 123) ... >>> t = Thing() >>> Thing.__getattribute__(t, '0potato') 123 >>> getattr(t, '0

通常的属性访问方法要求属性名为

但属性不必是有效的python标识符:

>>> class Thing:
...     def __init__(self):
...         setattr(self, '0potato', 123)
...         
>>> t = Thing()
>>> Thing.__getattribute__(t, '0potato')
123
>>> getattr(t, '0potato')
123
当然,
t.0potato
仍然是一个
SyntaxError
,但属性仍然存在:

>>> vars(t)
{'0potato': 123}
允许这样做的原因是什么?对于带有空格、空字符串、python保留关键字等的属性,真的有任何有效的用例吗?我认为原因是属性只是对象/名称空间dict中的键,但这毫无意义,因为不允许使用其他有效dict键的对象:

>>> setattr(t, ('tuple',), 321)
TypeError: attribute name must be string, not 'tuple'

因此,为了回答用例问题,从上面的注释中查看Python在引用中如何工作的背后的推理,我们可以推断出一些可能使这个Python怪癖有用的情况

  • 你希望一个对象有一个不能用点符号访问的属性,比如说,保护它不被天真的用户访问。(引用Guido的话:“有些人可能会用它来隐藏他们不希望使用常规属性表示法(x.foo)访问的状态。”当然,他接着说,“但对我来说,这感觉像是滥用了名称空间,还有很多其他方法。” 管理这种状态的方法。”)
  • 您希望对象的属性名称对应于您无法控制的外部数据。因此,您必须能够使用外部数据中出现的任何字符串作为属性名,即使它与Python保留字匹配或包含嵌入的空格或破折号等
  • 帖子上的详细信息完全回答了这个问题,因此我将其作为一个答案发布:

    说:

    …这是一种可以使用任意字符串的功能 使用getattr()和setattr()。但是,这些函数应该(也应该!) 拒绝非字符串

    可能的用例包括隐藏常规点访问的属性,以及使属性与外部数据源对应(这可能与Python关键字冲突)。因此,争论似乎是根本没有理由禁止它

    至于不允许非字符串的原因,这似乎是一个合理的限制,可以确保实现的更高性能:

    尽管Python的DICT已经有了一些仅限字符串的优化,但它们只是在第一个非键字符串出现时动态地适应一种更通用、速度稍慢的方法


    为什么允许这样做的答案可以在@poke的答案中找到。我不认为你的问题应该被欺骗,因为它要求合法的用例,而另一个只问为什么允许这样做。洛维斯的回应是。因此,它主要取决于
    \uuuu setattr\uuuu
    的底层实现,该实现可能接受非标识符。尽管可以创建一个接受元组的
    \uuuu setattr\uuuu
    ,但通过
    setattr
    调用时仍然失败。因此,内置方法似乎不仅仅是盲目地将其参数传递给对象的
    \uu setattr\uu
    方法。