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

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

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


当前回答

工厂方法(替代构造函数)确实是类方法的经典例子。

基本上,类方法适用于任何您希望有一个方法自然地适合类的名称空间,但不与类的特定实例相关联的时候。

例如,在excellent unipath模块中:

当前目录

Path.cwd () 返回实际的当前目录;例如,路径(“/ tmp / my_temp_dir”)。这是一个类方法。 .chdir () 使self为当前目录。

由于当前目录是进程范围的,cwd方法没有应该与之关联的特定实例。但是,将cwd更改为给定Path实例的目录确实应该是一个实例方法。

嗯…因为Path.cwd()确实返回了一个Path实例,我猜它可以被认为是一个工厂方法…

其他回答

它允许您编写可与任何兼容类一起使用的泛型类方法。

例如:

@classmethod
def get_name(cls):
    print cls.name

class C:
    name = "tester"

C.get_name = get_name

#call it:
C.get_name()

如果你不使用@classmethod,你可以用self关键字来做,但它需要一个Class的实例:

def get_name(self):
    print self.name

class C:
    name = "tester"

C.get_name = get_name

#call it:
C().get_name() #<-note the its an instance of class C

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

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

当然,类定义了一组实例。类的方法作用于单个实例。类方法(和变量)用于将与实例集相关的其他信息挂起。

例如,如果你的类定义了一组学生,你可能想要类变量或方法来定义学生可以成为成员的年级集。

您还可以使用类方法定义用于处理整个集合的工具。例如,Student.all_of_em()可能返回所有已知的学生。显然,如果您的实例集具有比集合更多的结构,您可以提供类方法来了解该结构。Students.all_of_em(等级=“下属”)

这样的技术往往会导致将实例集的成员存储到植根于类变量的数据结构中。这时,您需要注意避免使垃圾收集受挫。

工厂方法(替代构造函数)确实是类方法的经典例子。

基本上,类方法适用于任何您希望有一个方法自然地适合类的名称空间,但不与类的特定实例相关联的时候。

例如,在excellent unipath模块中:

当前目录

Path.cwd () 返回实际的当前目录;例如,路径(“/ tmp / my_temp_dir”)。这是一个类方法。 .chdir () 使self为当前目录。

由于当前目录是进程范围的,cwd方法没有应该与之关联的特定实例。但是,将cwd更改为给定Path实例的目录确实应该是一个实例方法。

嗯…因为Path.cwd()确实返回了一个Path实例,我猜它可以被认为是一个工厂方法…

@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']相同的值。