python

原创
2015/07/29 11:16
阅读数 580

昨天同事问我一个关于Python静态方法和类方法的区别,上网找了些资料整理一下:


@staticmethod和@classmethod都是用来定义静态函数的,它们的相同点是都不用实例化类,可以直接用类名来调用其相关属性。不同点 是,@classmethod的第一个参数是cls,因此可以访问类变量。@staticmethod只是自身代码在类里面,对类的其它再无相关。一般情 况下用@classmethod,@staticmethod只适用于不想定义全局函数的情况。


    下面是摘抄自Python核心编程第二版:

静态方法和类方法 

静态方法和类方法在 Python2.2 中引入。经典类及新式(new-style)类中都可以使用它。一对内

建函数被引入,用于将作为类定义的一部分的某一方法声明“标记”(tag),“强制类型转换”(cast)

或者“转换”(convert)为这两种类型的方法之一。 

如果你有一定的C++或者Java经验,静态方法和这些语言中的是一样的。它们仅是类中的函数(不

需要实例)。事实上,在静态方法加入到 Python 之前,用户只能在全局名字空间中创建函数,作为

这种特性的替代实现 - 有时在这样的函数中使用类对象来操作类(或者是类属性)。使用模块函数

比使用静态类方法更加常见。 

回忆一下,通常的方法需要一个实例(self)作为第一个参数,并且对于(绑定的)方法调用来

说,self 是自动传递给这个方法的。而对于类方法而言,需要类而不是实例作为第一个参数,它是

由解释器传给方法。类不需要特别地命名, 类似 self,不过很多人使用 cls 作为变量名字。 


staticmethod()和 classmethod()内建函数 

现在让我们看一下在经典类中创建静态方法和类方法的一些例子(你也可以把它们用在新式类

中): 

class TestStaticMethod: 

def foo(): 

print 'calling static method foo()' 

foo = staticmethod(foo) 

class TestClassMethod: 

def foo(cls): 

print 'calling class method foo()' 

print 'foo() is part of class:', cls.__name__ 

foo = classmethod(foo) 

对应的内建函数被转换成它们相应的类型,并且重新赋值给了相同的变量名。如果没有调用这

两个函数,二者都会在 Python 编译器中产生错误,显示需要带 self 的常规方法声明。现在, 我们

可以通过类或者实例调用这些函数....这没什么不同: 

>>> tsm = TestStaticMethod() 

>>> TestStaticMethod.foo() 

calling static method foo() 

>>> tsm.foo() 

calling static method foo() 

>>> 

>>> tcm = TestClassMethod() 

>>> TestClassMethod.foo() 

calling class method foo() 

foo() is part of class: TestClassMethod 

>>> tcm.foo() 

Edit By Vheavens 

Edit By Vheavens 

calling class method foo() 

foo() is part of class: TestClassMethod 


使用函数修饰符 

现在,看到像 foo=staticmethod(foo)这样的代码会刺激一些程序员。很多人对这样一个没意义

的语法感到心烦,即使 van Rossum 曾指出过,它只是临时的,有待社区对些语义进行处理。在第 11

章“函数”的 11.3.6 节中,我们了解了函数修饰符,一种在 Python2.4 中加入的新特征。你可以用

它把一个函数应用到另个函数对象上, 而且新函数对象依然绑定在原来的变量。我们正是需要它来

整理语法。通过使用 decorators,我们可以避免像上面那样的重新赋值: 

class TestStaticMethod: 

@staticmethod 

def foo(): 

print 'calling static method foo()' 

class TestClassMethod: 

@classmethod 

def foo(cls): 

print 'calling class method foo()' 

print 'foo() is part of class:', cls.__na


展开阅读全文
加载中
点击加入讨论🔥(2) 发布并加入讨论🔥
打赏
2 评论
14 收藏
0
分享
返回顶部
顶部