python 类设计(静态方法与方法)

发布于 2024-10-20 07:23:53 字数 466 浏览 8 评论 0原文

对于不需要任何传递信息(对象实例或类)的方法来说,更好的方法是什么,因为例如它们只进行简单的转换。 @staticmethod 还是方法

class Foo(object):
    def __init__(self, trees):
        self.money = Foo.trees2money(trees)

    @staticmethod
    def trees2money(trees):
        return trees * 1.337

class Quu(object):
    def __init__(self, trees):
        self.money = self.trees2money(trees)

    def trees2money(self, trees):
        return trees * 1.337

What's the nicer way for methods that don't need any passed information (object instance or class) because for example they just do a simple conversion. @staticmethod or method ?

class Foo(object):
    def __init__(self, trees):
        self.money = Foo.trees2money(trees)

    @staticmethod
    def trees2money(trees):
        return trees * 1.337

class Quu(object):
    def __init__(self, trees):
        self.money = self.trees2money(trees)

    def trees2money(self, trees):
        return trees * 1.337

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(3

最美的太阳 2024-10-27 07:23:53

方法类型的选择取决于其他因素。

你有两个案例。第一种情况是当该方法必须是类接口的一部分时 - 例如它必须由用户调用,或者它必须在子类中可重写,或者它使用 self 中的信息,或者很可能在未来版本中您可能需要其中任何一个软件。

在第一种情况下,您通常会使用普通方法(这是当该方法与实例而不是与类相关时)或classmethod(当该方法与类相关时,例如它是替代构造函数、发现类功能的方法等)。在这两种情况下,如果方法没有使用来自类/实例的信息,则可以使用静态方法,但这样做不会获得任何好处。而且它还会破坏你执行 cls.method(instance, *args) 的能力,这已经太多了,一无所获。

第二种情况是该方法无论如何都不属于类的一部分。那么通常建议使用函数 - 该方法实际上并不是接口的一部分,因此它在那里没有位置。你的例子似乎就是这种情况,除非你想覆盖子类中的树/金钱计算器,但这很大程度上取决于你用它做什么。

一个特殊情况是私有方法 - 那么你可能想要使用一个方法,即使它与类并不真正相关,私有方法不是接口的一部分,所以你把它们放在哪里并不重要。使用staticmethod仍然不会给你带来太多好处,但也没有任何理由不使用它。

实际上,在一种情况下,staticmethod 非常有用 - 当您将外部函数(或其他对象)放入类中时。

class Foo(object):
     trees2money = staticmethod(calculators.trees2money)
     foo = staticmethod(calculators.bar)

但是,当您拥有类的静态定义时,这并不是很好,因为您始终可以执行以下操作。

class Foo(object):
     def trees2money(self, trees):
         """Calculator for trees2money, you can override when subclassing"""
         return calculators.trees2money(trees)
     @property
     def foo(self):
         """The foo of the object"""
         return calculators.bar

这可以让您在阅读源代码时更好地了解这些对象的作用,甚至允许您添加文档。但当您动态构建类或将它们添加到元类中时(手动创建包装器方法不是很方便),它可能仍然会派上用场。

The choice of the type of method depends on other factors.

You have two cases. The first case is when the method has to be part of the class interface - e.g. it has to be called by users, or it has to be overridable in subclasses, or it uses the information in self, or it's likely that in a future version of the software you might need any of those.

In this first case you'd often either use a normal method (this is when the method relates to the instances and not to the class) or a classmethod (when the method relates to the class, e.g. it's an alternative constructor, a method for discovering class features, etc.). In both cases you can use a staticmethod instead if no information from the class/instance is used by the method, but you don't gain anything from doing so. And it would also break your ability to do cls.method(instance, *args) which is already too much for gaining nothing.

The second case is when the method isn't a part of the class in any way. Then it is generally advisable to use a function - the method is not really part of the interface, so it has no place there. Your example seems to be that case unless you want to override the tree/money calculator in subclasses, but that largely depends on what you're doing with it.

A special case is private methods - then you might want to use a method even if it's not really related to the class, private methods aren't part of the interface so it doesn't matter where you put them. Using a staticmethod still doesn't gain you much but there isn't any reason not to use it either.

There's actually one case where staticmethod is very helpful - when you're putting external functions (or other objects) in the class.

class Foo(object):
     trees2money = staticmethod(calculators.trees2money)
     foo = staticmethod(calculators.bar)

But when you have a static definition of the class, that's not really great, because you can always do the following instead.

class Foo(object):
     def trees2money(self, trees):
         """Calculator for trees2money, you can override when subclassing"""
         return calculators.trees2money(trees)
     @property
     def foo(self):
         """The foo of the object"""
         return calculators.bar

Which gives you a better idea what these objects do when reading the source and even allows you to add documentation. But it might still come in handy when you're building classes dynamically, or you're adding them in a metaclass (creating a wrapper method manually isn't very convenient).

心的憧憬 2024-10-27 07:23:53

对于所有面向对象的设计,我的一般规则是,如果类没有状态,请考虑使用静态方法。如果类有状态,请使用实例方法 - 毫无疑问。

此外,如果类确实没有状态,请反思几分钟,看看是否无法将静态行为移近数据,从而使用 提取方法重构。

My general rule, for all Object Oriented design, is that if a class has no state, consider using static methods. If the class has state, use instance methods - hands down.

Furthermore, if the class indeed has no state, reflect for a few minutes and see if you cannot move the static behavior closer to the data and thereby eliminate those static methods with an Extract Method refactoring.

断桥再见 2024-10-27 07:23:53

任何不使用对象命名空间中的名称的方法都应该使用类方法,而那些不使用类命名空间中的名称的方法也应该使用静态方法,甚至可以将其作为函数放在模块级别。

当使用实际的对象方法时,预期的行为是访问同一对象的一些其他属性/方法。

Any methods that do not use names from the object namespace should by classmethods, and those that do not use names from the class namespace either - staticmetdods, or even be put on the module level as functions.

When the actual object method is used, the expected behavior is that some other attrubutes/methods from the same object will be accessed.

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