我正在学习 python,虽然我认为我了解了 Python 的整个概念和概念,但今天我偶然发现了一段我没有完全理解的代码:
假设我有一个应该定义 Circles 但缺少主体的类:
class Circle():
pass
由于我没有定义任何属性,我该怎么做:
my_circle = Circle()
my_circle.radius = 12
奇怪的是 Python 接受了上面的语句。我不明白为什么 Python 不引发 undefined name error
。我知道通过 动态类型 我只是在需要时将变量绑定到对象,但是属性 radius
不应该存在于 Circle
类中以允许我这样做吗?
编辑:你的答案中有很多精彩的信息! 谢谢大家所有这些精彩的答案! 很遗憾我只能标记一个作为答案。
原文由 NlightNFotis 发布,翻译遵循 CC BY-SA 4.0 许可协议
一个主要原则是 _没有声明这样的东西_。也就是说,你永远不会声明“这个类有一个方法 foo”或“这个类的实例有一个属性 bar”,更不用说声明要存储在那里的对象的类型了。您只需定义一个方法、属性、类等,然后将其添加。正如 JBernardo 指出的那样,任何
__init__
方法都做同样的事情。任意将新属性的创建限制为名称为__init__
的方法没有多大意义。有时将函数存储为__init__
是有用的,它实际上没有那个名称(例如装饰器),这样的限制会破坏它。现在,这不是普遍正确的。作为优化,内置类型忽略了此功能。通过
__slots__
,您还可以在用户定义的类上防止这种情况。但这仅仅是空间优化(不需要每个对象的字典),而不是正确性。如果你想要一个安全网,那就太糟糕了。 Python 不提供,您也无法合理地添加一个,最重要的是,拥抱该语言的 Python 程序员会回避它(阅读:几乎所有您想与之合作的人)。测试和纪律对于确保正确性还有很长的路要走。不要随意在
__init__
之外编造属性, 如果可以避免 的话,做自动化测试。我很少有AttributeError
或由于像这样的诡计而导致的逻辑错误,并且在发生的那些中,几乎所有都被测试捕获。