小编典典

为什么允许向已实例化的对象添加属性?

python

我正在研究python,尽管我认为我了解了Python的全部概念和概念,但今天我偶然发现了一段我不完全理解的代码:

假设我有一个本应定义Circles但缺少主体的类:

class Circle():
    pass

由于我尚未定义任何属性,因此该如何做:

my_circle = Circle()
my_circle.radius = 12

奇怪的是,Python接受上述声明。我不明白为什么Python不会引发undefined name error。我确实知道,通过 动态类型化,
我只是在需要时将变量绑定到对象,但是类中不应该radius存在Circle允许我执行此操作的属性吗?

编辑 :您的答案中有很多精彩的信息! 谢谢大家的精彩回答! 很遗憾,我只能将其中一个标记为答案。


阅读 217

收藏
2020-12-20

共1个答案

小编典典

一个主要原则是 没有声明
。也就是说,您永远不会声明“此类具有方法foo”或“此类的实例具有属性栏”,更不用说声明要存储在其中的对象类型了。您只需定义一个方法,属性,类等,然后将其添加。正如JBernardo指出的那样,任何__init__方法都可以做同样的事情。随意将新属性的创建限制为名称为方法的方法没有多大意义__init__。有时将__init__实际上没有该名称的函数(例如,装饰器)存储起来很有用,而这样的限制会破坏这一点。

现在,这并非普遍如此。内置类型忽略此功能作为优化。通过__slots__,您还可以在用户定义的类中防止这种情况。但这仅仅是空间优化(不需要每个对象都有字典),而不是正确性。

如果您想要一个安全网,那就太糟糕了。Python没有提供一种语言,您不能合理地添加一种语言,最重要的是,使用该语言的Python程序员会避免使用它(阅读:几乎所有您想使用的语言)。测试和纪律,对于确保正确性还有很长的路要走。__init__
如果可以避免
,请不要使用自由来补充属性,而要进行自动化测试。我很少会AttributeError因为这样的诡计而出现逻辑错误,在发生的那些错误中,几乎所有错误都会被测试捕获。

2020-12-20