这实际上是两个问题:
1)在声明python类时,变量默认为static而方法默认为实例,这背后的逻辑是什么?我知道我可以在_ init _ 中声明变量或者将@staticmethod或@classmethod添加到方法中以将它们翻转到另一侧,但它似乎(至少对我而言)让它们一直默认为方式或其他方式(例如像Java / C#)会更有意义。
我是否有一些非常常见的用例?我知道实现是这样的,但肯定一定是设计决定以这种方式使用它,方法默认为实例但是变量默认恰好相反。
2)有没有办法在python类中声明实例变量而不将它们放在_ init _ 中?
我知道我可以将它们放在_ init _ 中,但这需要任何需要自己的_ init _ 的子类:
A)自己宣布或
B)手动调用基类_ init _ 本身,
这两个都很痛苦。我能做到,但感觉很脏;子类应该只需要在类声明中的(BaseClass)工作,它们不需要在自己的_ init _ 中调用任何特殊的东西,以使BaseClass功能完全工作答案 0 :(得分:3)
我相信你所反对的是与读取模块时处理/评估事物的方式有关。
class Parent(object):
someAttr = Parser() # Static variable - created as the class is parsed.
def __init__(self):
self.otherAttr = Reader() # Instance - created when the class is instantiated.
class Child(Parent): pass
Child将拥有静态someAttr
以及实例otherAttr
,因为它没有覆盖Parent的__init__
方法。如果不需要特殊的__init__
处理,则不必让每个子类创建相同的实例变量。如果它没有提供它自己的一个,它将自动调用它的__init__
。希望这能澄清一些。
答案 1 :(得分:2)
1)Python实现类的方法与Java和C#等语言有很大不同。它非常灵活,您可以覆盖和修改其行为的几乎每个部分,实际上您可以控制它们的工作方式。
类属性只是存在于类的命名空间中的对象。对象本身定义了从实例或类访问期间的行为,这通过所谓的描述符协议发生。不实现描述符协议的对象就像你所谓的“静态”对象一样(例如,来自类的只读访问和实例是相同的)。函数,类方法对象,属性等对象实现了这个协议。
您不需要知道详细信息,但它是定义行为的对象:
2)你应该总是调用超类的__init__
(而不是父类)。这通常使用super(CurrentClass, self).__init__(*args, **kwargs)