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
。 允许以这种方式定义实例变量的好理由是什么?而且,危险吗?为什么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
。 允许以这种方式定义实例变量的好理由是什么?而且,危险吗?为什么Python允许在初始化后添加实例变量?
允许以这种方式定义实例变量的好理由是什么?
我认为需要注意的是self
您__init__
函数内部是完全一样在该实例上的任何其他方法self
是很重要的。这与班级以外的a
相同。 __init__
方法的神奇之处在于当被调用时,而没有其他东西(这是所有真正的python魔术方法)。要让__init__
以某种方式“冻结”对象,将会违背python中一直采用的方式。
所以,我会说“好理由”是因为它使事情非常一致。
而且,危险吗?
是的。有可能。
的故意添加方法的实践/属性实例被称为猴修补(也被称为偶尔冲鸭) - 它真的不应该这样做,除非你没有其他任何选项。
无意中的做法将方法/属性添加到实例称为创建错误(我们已经完成了它:-)。
幸运的是,有工具可以帮助您防止这些类型的错误。 Linters是最常见的。我个人使用pylint
来帮助我警告我这些类型的错误。
在linter和使用常识(见上面有关不Monkey Scatch)之间,由于python的意识形态的这部分,我很少遇到难以追踪的bug。
我想如果你在后面的实例方法中添加更多的属性,它不是鸭子冲 - 但你可能不应该这样做。 。 。
我认为这符合python原则“我们都是负责任的用户”。看到这里:http://docs.python-guide.org/en/latest/writing/style/
这是一个很好的答案! –
然后接受它:) – Jasper
“为什么?”没有好的答案。题。这是Python思想体系的一部分。 Python结合了来自几种不同编程范例的元素,以适应不同的编码风格。你可以编写功能性的,纯粹的面向对象的,结构化的(如果你年老而不是非常明亮),或者甚至是事件驱动,如果你想变得更加花哨和异步。它本质上并不危险,但是像许多其他语言一样,它允许你用自己的脚来拍摄自己(也可能是其他开发团队的成员)。
在python中,你也可以动态地添加函数方法。这里是你可能会感兴趣的东西[what-is-a-metaclass-in-python](http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python)答案“类和对象“给出了一个安静的好概况! – keksnicoh