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

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

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


当前回答

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

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

其他回答

当用户登录我的网站时,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()

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

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

例如:

@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

我以前用过PHP,最近我在问自己,这个类方法是怎么回事?Python手册是非常技术性的,非常简短的文字,所以它不会帮助理解这个功能。我一直在谷歌上搜索,然后我找到了答案——> http://code.anjanesh.net/2007/12/python-classmethods.html。

如果你懒得点击它。我的解释很简短。:)

在PHP中(也许不是所有人都知道PHP,但是这个语言非常直接,每个人都应该明白我在说什么),我们有这样的静态变量:


class A
{

    static protected $inner_var = null;

    static public function echoInnerVar()
    {
        echo self::$inner_var."\n";
    }

    static public function setInnerVar($v)
    {
        self::$inner_var = $v;
    }

}

class B extends A
{
}

A::setInnerVar(10);
B::setInnerVar(20);

A::echoInnerVar();
B::echoInnerVar();

在这两种情况下,输出都是20。

但是在python中,我们可以添加@classmethod装饰器,这样就可以分别输出10和20。例子:


class A(object):
    inner_var = 0

    @classmethod
    def setInnerVar(cls, value):
        cls.inner_var = value

    @classmethod
    def echoInnerVar(cls):
        print cls.inner_var


class B(A):
    pass


A.setInnerVar(10)
B.setInnerVar(20)

A.echoInnerVar()
B.echoInnerVar()

聪明,不是吗?

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

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