Python 类静态/实例默认值
这实际上是两个问题:
1)声明Python类时,变量默认为静态,方法默认为实例,背后的逻辑是什么?我知道我可以在 _init _ 中声明变量,或者将 @staticmethod 或 @classmethod 添加到方法中以将它们翻转到另一侧,但似乎(至少对我来说)让它们始终默认一个方式或其他方式(例如Java/C#)会更有意义。
我缺少一些非常常见的用例吗?我知道实现是这样的,但肯定是这样的设计决定,方法默认为实例,但变量默认为完全相反。
2)有没有办法在python类中声明实例变量而不将它们放在_init _中?
我知道我可以将它们放入 _init _ 中,但这需要任何需要自己的 _init _ 的子类:
A) 自己声明它们或
B) 手动 声明它们调用基类 _init _ 本身,
这两者都很痛苦。我可以做到,但感觉很脏;子类化某些东西只需要类声明中的 (BaseClass) 即可工作,它们不需要在自己的 _init _ 中调用任何特殊内容以使 BaseClass 功能充分工作
This is actually two questions:
1) What is that logic behind the fact that, when declaring a python class, do variables default to static and methods default to instance? I know i can declare variables in _init _ or add @staticmethod or @classmethod to methods to flip them to the other side, but it just seems (to me at least) having them both consistently default one way or another (e.g. like Java/C#) would make much more sense.
Is there some very common use case i am missing? I know the implementation is as such, but surely it must have been a design decision to have it this way, having methods default to instance but having variables default to exactly the opposite.
2) Is there any way to declare instance variables in python classes without putting them in _init _?
I know i can put them in _init _, but that would require any subclasses which need their own _init _ to either:
A) declare them himself or
B) manually call the base classes _init _ themselves,
both of which are a pain. I could do it, but it feels dirty; subclasses something should require nothing more than the (BaseClass) in the class declaration to work, they should not need to call anything special in their own _init _ for the BaseClass functionality to work fully
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我相信您遇到的问题与读入模块时处理/评估事物的方式有关。Child
将具有静态
someAttr
以及实例otherAttr
因为它没有重写父级的__init__
方法。如果不需要特殊的 __init__ 处理,则不必让每个子类创建相同的实例变量。如果它没有提供自己的一个,它将自动调用父级的__init__
。希望这能澄清一些。I believe what you're up against is related to the way that things are processed / evaluated as the modules are read in.
Child will have the static
someAttr
and also the instanceotherAttr
because it did not override the__init__
method from the Parent. You don't have to have each child class create the same instance variables if it does not require special__init__
handling. It will automatically call the Parent's__init__
if it hasn't provided one of its own. Hopefully that clarifies some.1) Python 实现类的方法与 Java 和 C# 等语言有很大不同。它非常灵活,您可以覆盖和修改其行为的几乎每个部分,您实际上可以控制它们工作方式的实现。
类属性只是存在于类的命名空间中的对象。对象本身定义从实例或类访问期间的行为,这通过所谓的描述符协议发生。不实现描述符协议的对象的行为就像您所说的“静态”对象(例如,来自类和实例的只读访问是相同的)。诸如函数、类方法对象、属性之类的对象实现了该协议。
您不需要了解细节,但定义行为的是对象:
2)您应该始终调用超类(而不是父类)的
__init__
。这通常使用 super(CurrentClass, self).__init__(*args, **kwargs) 来完成。1) Python's approach for implementing classes is very different from languages like Java and C#. It's very flexible, and you can override and modify almost every part of its behaviour, you actually have control over the implementation of how they work.
Class attributes are just objects that live in the namespace of the class. The object themselves define the behaviour during access from the instance or the class, this happens through the so-called descriptor protocol. Objects that do not implement the descriptor protocol act like what you call "static" objects (e.g. read-only access from the class and the instance is the same). Objects such as functions, classmethod objects, properties implement this protocol.
You don't need to know the details, but it's the object that defines the behaviour:
2) You should always call the
__init__
of the superclass (as opposed to the parent class). This is commonly done usingsuper(CurrentClass, self).__init__(*args, **kwargs)