为什么 Python 允许在初始化后添加实例变量?
Why does Python allow instance variables to be added after initialization?
class MyClass(object):
class_var = []
def __init__(self, i_var):
self.i_var = i_var
a = MyClass(2)
a.hit = 1
print a.hit
我们可以看到,hit
初始化后作为实例变量添加到a
中。
允许以这种方式定义实例变量的充分理由是什么?还有,危险吗?
我觉得正好符合''we are all responsible users''的python原则。看这里:http://docs.python-guide.org/en/latest/writing/style/
What's a good reason to allow defining instance variable in such a way?
我认为重要的是要注意 __init__
函数中的 self
与该实例的任何其他方法中的 self
完全相同。它也与 class 之外的 a
相同。 __init__
方法的魔力在于 when 它被调用而不是其他(all python魔术方法)。 __init__
"freeze" 对象以这样或那样的方式将违背 python.
中一直做事的方式
所以,我会说 "good reason" 是因为它使事情非常一致。
And, is it dangerous?
是的。可以。
有意将methods/attributes添加到实例的做法称为 Monkey Patching(有时也称为 Duck Punching)1 -- 除非你没有任何其他选择,否则真的不应该这样做。
无意 将 methods/attributes 添加到实例的做法被称为制造错误(我们都这样做过 :-)。
幸运的是,有一些工具可以帮助您防止这些类型的错误。 Linter 是最常见的。我个人使用 pylint
来帮助警告我这些错误。
在 linter 和使用常识之间(参见上面关于非 Monkey Patching 的内容),由于 python 的意识形态的这一部分,我很少遇到 hard-to-track 错误。
1我想如果你在后面的实例方法中添加更多的属性,那不是鸭子打孔——但你可能不应该这样做那要么。 . .
"why?" 问题没有好的答案。这是 python 意识形态的一部分。 Python 合并了来自几种不同编程范例的元素以适应不同的编码风格。您可以编写函数式的、纯面向对象的、结构化的(如果您年纪大而且不是很聪明),或者如果您想要更加花哨和异步,甚至可以编写事件驱动的。它本身并不危险,但就像许多其他语言的优点一样,它确实会让你搬起石头砸自己的脚(也可能是开发团队的其他成员)。
class MyClass(object):
class_var = []
def __init__(self, i_var):
self.i_var = i_var
a = MyClass(2)
a.hit = 1
print a.hit
我们可以看到,hit
初始化后作为实例变量添加到a
中。
允许以这种方式定义实例变量的充分理由是什么?还有,危险吗?
我觉得正好符合''we are all responsible users''的python原则。看这里:http://docs.python-guide.org/en/latest/writing/style/
What's a good reason to allow defining instance variable in such a way?
我认为重要的是要注意 __init__
函数中的 self
与该实例的任何其他方法中的 self
完全相同。它也与 class 之外的 a
相同。 __init__
方法的魔力在于 when 它被调用而不是其他(all python魔术方法)。 __init__
"freeze" 对象以这样或那样的方式将违背 python.
所以,我会说 "good reason" 是因为它使事情非常一致。
And, is it dangerous?
是的。可以。
有意将methods/attributes添加到实例的做法称为 Monkey Patching(有时也称为 Duck Punching)1 -- 除非你没有任何其他选择,否则真的不应该这样做。
无意 将 methods/attributes 添加到实例的做法被称为制造错误(我们都这样做过 :-)。
幸运的是,有一些工具可以帮助您防止这些类型的错误。 Linter 是最常见的。我个人使用 pylint
来帮助警告我这些错误。
在 linter 和使用常识之间(参见上面关于非 Monkey Patching 的内容),由于 python 的意识形态的这一部分,我很少遇到 hard-to-track 错误。
1我想如果你在后面的实例方法中添加更多的属性,那不是鸭子打孔——但你可能不应该这样做那要么。 . .
"why?" 问题没有好的答案。这是 python 意识形态的一部分。 Python 合并了来自几种不同编程范例的元素以适应不同的编码风格。您可以编写函数式的、纯面向对象的、结构化的(如果您年纪大而且不是很聪明),或者如果您想要更加花哨和异步,甚至可以编写事件驱动的。它本身并不危险,但就像许多其他语言的优点一样,它确实会让你搬起石头砸自己的脚(也可能是开发团队的其他成员)。