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

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

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


当前回答

当用户登录我的网站时,user()对象从用户名和密码实例化。

如果我需要一个没有用户在那里登录的用户对象(例如,一个管理用户可能想要删除另一个用户帐户,所以我需要实例化该用户并调用它的delete方法):

我有类方法来获取用户对象。

class User():
    #lots of code
    #...
    # more code

    @classmethod
    def get_by_username(cls, username):
        return cls.query(cls.username == username).get()

    @classmethod
    def get_by_auth_id(cls, auth_id):
        return cls.query(cls.auth_id == auth_id).get()

其他回答

类方法提供了“语义糖”(不知道这个术语是否被广泛使用)——或者“语义便利”。

例如:你有一组表示对象的类。你可能想让类方法all()或find()写User.all()或User.find(firstname='Guido')。当然,这可以使用模块级函数来实现……

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

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

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

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

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

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

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

诚实?我从未发现staticmethod或classmethod的用途。我还没有看到一个操作不能使用全局函数或实例方法来完成。

如果python像Java那样使用private和protected成员,情况将有所不同。在Java中,我需要一个静态方法来访问实例的私有成员来做一些事情。在Python中,很少需要这样做。

通常,我看到人们使用静态方法和类方法,而他们真正需要做的只是更好地使用python的模块级名称空间。