我正在自学Python,我最近的一课是Python不是Java,所以我刚刚花了一段时间把我所有的Class方法变成了函数。

我现在意识到,我不需要使用Class方法来做我在Java中使用静态方法所做的事情,但现在我不确定什么时候我会使用它们。我能找到的所有关于Python类方法的建议都是,像我这样的新手应该避开它们,而标准文档在讨论它们时是最不透明的。

谁有一个在Python中使用类方法的好例子,或者至少有人能告诉我什么时候可以合理地使用类方法吗?


当前回答

@classmethod对于从外部资源轻松实例化该类的对象非常有用。考虑以下几点:

import settings

class SomeClass:
    @classmethod
    def from_settings(cls):
        return cls(settings=settings)

    def __init__(self, settings=None):
        if settings is not None:
            self.x = settings['x']
            self.y = settings['y']

然后在另一个文件中:

from some_package import SomeClass

inst = SomeClass.from_settings()

访问inst.x将得到与settings['x']相同的值。

其他回答

替代构造函数是经典的例子。

我从Ruby学到的是,所谓的类方法和所谓的实例方法只是一个函数,它的第一个参数具有语义意义,当函数作为对象的方法(即obj.meth())调用时,该参数会被无声地传递。

通常,该对象必须是一个实例,但@classmethod方法装饰器更改规则以传递一个类。你可以在一个实例上调用一个类方法(它只是一个函数)-第一个参数将是它的类。

因为它只是一个函数,所以在任何给定的作用域(即类定义)中只能声明一次。因此,对于ruby开发者来说,你不能让一个类方法和一个实例方法同名。

考虑一下:

class Foo():
  def foo(x):
    print(x)

你可以在实例上调用foo

Foo().foo()
<__main__.Foo instance at 0x7f4dd3e3bc20>

但不是在课堂上:

Foo.foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method foo() must be called with Foo instance as first argument (got nothing instead)

现在添加@classmethod:

class Foo():
  @classmethod
  def foo(x):
    print(x)

调用一个实例现在会通过它的类:

Foo().foo()
__main__.Foo

调用类也一样:

Foo.foo()
__main__.Foo

按照惯例,我们在实例方法中使用self作为第一个参数,在类方法中使用cls。我在这里用这两个都不是来说明它只是一个论点。在Ruby中,self是一个关键字。

与Ruby的对比:

class Foo
  def foo()
    puts "instance method #{self}"
  end
  def self.foo()
    puts "class method #{self}"
  end
end

Foo.foo()
class method Foo

Foo.new.foo()
instance method #<Foo:0x000000020fe018>

Python类方法只是一个装饰函数,您可以使用相同的技术来创建自己的装饰器。修饰过的方法包装了真正的方法(在@classmethod的情况下,它传递了额外的类参数)。底层的方法仍然存在,隐藏但仍然可以访问。


脚注:在类和实例方法之间的名称冲突引起了我的好奇心之后,我写了这篇文章。我不是Python专家,如果有任何错误,我希望得到评论。

类方法用于当您需要不特定于任何特定实例,但仍以某种方式涉及类的方法时。最有趣的是,它们可以被子类覆盖,这在Java的静态方法或Python的模块级函数中是不可能的。

如果你有一个类MyClass,和一个模块级的函数,它操作MyClass(工厂,依赖注入存根等),让它成为一个类方法。然后它将可用于子类。

我也问过自己几次同样的问题。尽管这里的人试图努力解释它,恕我直言,我找到的最好的答案(也是最简单的)答案是Python文档中对Class方法的描述。

还有对静态方法的引用。如果有人已经知道实例方法(我假设是这样),这个答案可能是把它们放在一起的最后一块……

关于这个主题的进一步和更深入的阐述也可以在文档中找到: 标准类型层次结构(向下滚动到实例方法部分)

类和对象概念在组织事物时非常有用。的确,方法可以完成的所有操作也可以使用静态函数完成。

设想一个场景,构建一个学生数据库系统来维护学生的详细信息。 你需要了解学生、老师和员工的详细信息。您需要构建计算费用、工资、分数等的函数。费用和分数只适用于学生,工资只适用于员工和教师。因此,如果您为每种类型的人创建单独的类,代码将被组织起来。