这实际上是两个问题:
1(在声明python类时,变量默认为静态,方法默认为实例,这背后的逻辑是什么?我知道我可以在 _init _ 中声明变量或向方法添加@staticmethod或@classmethod以将它们翻转到另一边,但似乎(至少对我来说(让它们都始终以一种或另一种方式默认(例如像 Java/C#(会更有意义。
我缺少一些非常常见的用例吗?我知道实现是这样的,但肯定是这样的设计决策,让方法默认为实例,但让变量默认为完全相反。
2(有没有办法在python类中声明实例变量而不将它们放在_init _中?
我知道我可以将它们放在 _init _ 中,但这需要任何需要自己的 _init _ 的子类来:
A( 自己声明或
B( 手动调用基类 _init _ 自己,
两者都是一种痛苦。我可以做到,但感觉很脏;子类的东西应该只需要类声明中的(BaseClass(就可以工作,它们不需要在自己的_init_中调用任何特殊的东西,BaseClass功能就可以完全工作
您遇到的与读取模块时处理/评估事物的方式有关。
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
子级将具有静态someAttr
以及实例otherAttr
,因为它没有覆盖父级中的__init__
方法。 如果不需要特殊__init__
处理,则不必让每个子类创建相同的实例变量。 如果它没有提供自己的__init__
,它将自动调用父级的。 希望这能澄清一些问题。
1(Python实现类的方法与Java和C#等语言非常不同。它非常灵活,您可以覆盖和修改其行为的几乎每个部分,您实际上可以控制它们的工作方式的实现。
类属性只是位于类的命名空间中的对象。对象本身定义从实例或类访问期间的行为,这是通过所谓的描述符协议发生的。不实现描述符协议的对象的行为类似于您所谓的"静态"对象(例如,来自类和实例的只读访问是相同的(。函数、类方法对象、属性等对象实现此协议。
您不需要知道细节,但定义行为的是对象:
- 函数想要像方法一样工作 属性
- 希望允许您定义属性的行为方式
- 静态方法删除任何自定义行为(staticmethod对象只需包装函数对象并禁用描述符协议;它们可以包装任何对象(
2( 您应该始终调用超类(而不是父类(的__init__
。这通常使用super(CurrentClass, self).__init__(*args, **kwargs)