我正在自学Python,我最近的一课是Python不是Java,所以我刚刚花了一段时间把我所有的Class方法变成了函数。
我现在意识到,我不需要使用Class方法来做我在Java中使用静态方法所做的事情,但现在我不确定什么时候我会使用它们。我能找到的所有关于Python类方法的建议都是,像我这样的新手应该避开它们,而标准文档在讨论它们时是最不透明的。
谁有一个在Python中使用类方法的好例子,或者至少有人能告诉我什么时候可以合理地使用类方法吗?
我正在自学Python,我最近的一课是Python不是Java,所以我刚刚花了一段时间把我所有的Class方法变成了函数。
我现在意识到,我不需要使用Class方法来做我在Java中使用静态方法所做的事情,但现在我不确定什么时候我会使用它们。我能找到的所有关于Python类方法的建议都是,像我这样的新手应该避开它们,而标准文档在讨论它们时是最不透明的。
谁有一个在Python中使用类方法的好例子,或者至少有人能告诉我什么时候可以合理地使用类方法吗?
当前回答
我也问过自己几次同样的问题。尽管这里的人试图努力解释它,恕我直言,我找到的最好的答案(也是最简单的)答案是Python文档中对Class方法的描述。
还有对静态方法的引用。如果有人已经知道实例方法(我假设是这样),这个答案可能是把它们放在一起的最后一块……
关于这个主题的进一步和更深入的阐述也可以在文档中找到: 标准类型层次结构(向下滚动到实例方法部分)
其他回答
类和对象概念在组织事物时非常有用。的确,方法可以完成的所有操作也可以使用静态函数完成。
设想一个场景,构建一个学生数据库系统来维护学生的详细信息。 你需要了解学生、老师和员工的详细信息。您需要构建计算费用、工资、分数等的函数。费用和分数只适用于学生,工资只适用于员工和教师。因此,如果您为每种类型的人创建单独的类,代码将被组织起来。
类方法用于当您需要不特定于任何特定实例,但仍以某种方式涉及类的方法时。最有趣的是,它们可以被子类覆盖,这在Java的静态方法或Python的模块级函数中是不可能的。
如果你有一个类MyClass,和一个模块级的函数,它操作MyClass(工厂,依赖注入存根等),让它成为一个类方法。然后它将可用于子类。
我认为最明确的答案是AmanKow的答案。归根结底,这取决于你想如何组织你的代码。你可以把所有东西都写成模块级的函数,这些函数被包装在模块的命名空间中
module.py (file 1)
---------
def f1() : pass
def f2() : pass
def f3() : pass
usage.py (file 2)
--------
from module import *
f1()
f2()
f3()
def f4():pass
def f5():pass
usage1.py (file 3)
-------------------
from usage import f4,f5
f4()
f5()
上面的过程代码组织得不好,正如你所看到的,只有3个模块后,它变得令人困惑,每个方法是做什么的?你可以为函数使用较长的描述性名称(如在java中),但你的代码仍然很快变得难以管理。
面向对象的方法是将代码分解为可管理的块,即类和对象,函数可以与对象、实例或类相关联。
与模块级函数相比,使用类函数可以在代码中获得另一个级别的除法。 因此,您可以在类中对相关函数进行分组,使它们更特定于分配给该类的任务。例如,你可以创建一个文件工具类:
class FileUtil ():
def copy(source,dest):pass
def move(source,dest):pass
def copyDir(source,dest):pass
def moveDir(source,dest):pass
//usage
FileUtil.copy("1.txt","2.txt")
FileUtil.moveDir("dir1","dir2")
这种方式更灵活,更可维护,您将函数分组在一起,并且每个函数的功能更明显。此外,您还可以防止名称冲突,例如,函数副本可能存在于您在代码中使用的另一个导入模块中(例如网络副本),因此当您使用全名FileUtil.copy()时,您可以消除这个问题,并且两个复制函数可以并排使用。
它允许您编写可与任何兼容类一起使用的泛型类方法。
例如:
@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()
聪明,不是吗?