Python中的静态类

Python中的静态类,python,class,static,instance,class-method,Python,Class,Static,Instance,Class Method,我曾经读过(我想是在微软的一个页面上),当您不需要一个类的两个或多个实例时,使用静态类是一种很好的方法 我正在用Python编写一个程序。如果我对一个类的每个方法都使用@classmethod,这是一种糟糕的风格吗?一般来说,这样的使用最好只使用模块中的函数,而不使用任何类。这是一种糟糕的风格,除非您确实需要访问该类 静态方法[…]不会转换为Python类方法。当然,这或多或少会产生相同的效果,但classmethod的目标实际上是做一些通常不可能的事情[…](比如继承非默认构造函数)。[…]静

我曾经读过(我想是在微软的一个页面上),当您不需要一个类的两个或多个实例时,使用静态类是一种很好的方法


我正在用Python编写一个程序。如果我对一个类的每个方法都使用
@classmethod
,这是一种糟糕的风格吗?

一般来说,这样的使用最好只使用模块中的函数,而不使用任何类。

这是一种糟糕的风格,除非您确实需要访问该类

静态方法[…]不会转换为Python类方法。当然,这或多或少会产生相同的效果,但classmethod的目标实际上是做一些通常不可能的事情[…](比如继承非默认构造函数)。[…]静态方法的惯用翻译通常是模块级函数,而不是classmethod或staticmethod


对此,您可以采取几种方法。正如其他人提到的,您可以只使用模块级函数。在本例中,模块本身就是将它们放在一起的名称空间。如果需要跟踪状态,另一个选项可能很有用,那就是使用普通方法(采用self)定义一个类,然后定义该类的单个全局实例,并将其实例方法复制到模块名称空间。这是标准库“random”模块采用的方法——看看python目录中的
lib/python2.5/random.py
。在底部,它有如下内容:

# Create one instance, seeded from current time, and export its methods
# as module-level functions.  [...]
_inst = Random()
seed = _inst.seed
random = _inst.random
uniform = _inst.uniform
...

或者您可以采用您描述的基本方法(尽管我建议在大多数情况下使用
@staticmethod
而不是
@classmethod

根据我的经验,创建类是一个非常好的解决方案,原因有很多。一个是,您最终将该类作为“普通”类使用(尤其是生成多个实例)的频率比您想象的要高。这也是一个合理的风格选择,坚持课堂上的每一件事;这可以让其他人更容易阅读/维护您的代码,特别是如果他们是非常面向对象的-他们会对类感到舒服。正如在其他回复中所指出的,在实现中使用“裸”函数也是合理的。你可能希望从一个类开始,使它成为一个singleton/Borg模式(如果你在谷歌上搜索这些,有很多例子);它使您可以灵活地(重新)使用该类来满足其他需求。我建议不要使用“静态类”方法,因为它是非传统的、非python的,这会使它更难阅读和维护。

实际上,您可能希望使用单例类而不是静态类:

+1。如果不封装任何数据,绝对不需要在Python中创建类。我有时只从函数开始,但后来意识到,因为我喜欢编写小函数,有时必须在其中3或4个函数之间传递相同的参数,此时我开始想要封装该参数。我还没有解决这个难题。想法?@Leonid我认为如果你的函数是独立的,但仍然需要它们之间的参数,只需传递这些参数。如果您发现有许多调用都具有相同的参数集合,那么可能会生成一个
namedtuple
或一些要传递的内容。将东西存储在类中以避免传递通常是一个坏主意——这可能会导致问题。@Lattyware,我不喜欢将状态作为一种哲学,但真正的函数式语言(如F#、Clojure、Haskell)仍然占据着相当小的位置。Python是一种多范式语言,因此如何使用它通常取决于程序员。下面的内容相当模糊:“在类中存储东西只是为了避免传递它们,这通常是一个坏主意——它可能会导致问题。”。你能详细说明具体的危险、问题和缺点吗?否则,我可能会认为您对函数和对象有偏见。@Leonid我绝对不主张完全避免状态,尤其是在Python中。我的意思是,如果不应该在值的生命周期是函数调用的生命周期的情况下使用在类中存储值,那么从字面上说就是为了避免通过子函数传递值。危险在于,这种状态可能突然在外部发生变异(比如函数在其他地方运行),从而导致bug和脆弱性。由于这些函数依赖于这种状态,因此也降低了它们的重用能力。您的大多数回答(第二句和最后一句是主要的例外)都是有争议的(我倾向于不同意),而且离题了。我想说的是,减少所有关于课程有多好的枝节会改善它,你认为呢?我同意也不同意这个答案。所以我不能决定是按向上键还是向下键。无论如何,我同意对象使代码更易于阅读和维护。我不同意使用singleton/borg模式。这并不是说这是一个坏模式;然而,在极其复杂的代码项目中,使用带有类变量的静态方法更容易维护和读取。是的,这在技术上可能不正确,但初级程序员会感谢您。