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

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

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


当前回答

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

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

其他回答

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

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

例如,在excellent unipath模块中:

当前目录

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

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

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

我以前用过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()

聪明,不是吗?

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

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

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

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

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

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

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