Python 类静态/实例默认值

发布于 2024-11-27 05:25:19 字数 565 浏览 1 评论 0原文

这实际上是两个问题:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陌生 2024-12-04 05:25:19

我相信您遇到的问题与读入模块时处理/评估事物的方式有关。Child

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__ 。希望这能澄清一些。

I believe what you're up against is related to the way that things are processed / evaluated as the modules are read in.

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 will have the static someAttr and also the instance otherAttr 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.

又怨 2024-12-04 05:25:19

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:

  • Functions want to act like methods
  • Properties want to let you define how the attribute acts
  • Static methods remove any custom behaviour (staticmethod objects simply wrap the function object and disable the descriptor protocol; they can wrap any object)

2) You should always call the __init__ of the superclass (as opposed to the parent class). This is commonly done using super(CurrentClass, self).__init__(*args, **kwargs)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文