24.静态方法和类方法

 

 

静态方法和类方法

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

 通常的方法需要一个实例(self)作为第一个参数,并且对于(绑定的)方法调用来说,self 是自动传递给这个方法的。而对于类方法而言,需要类而不是实例作为第一个参数,它是由解释器传给方法。类不需要特别地命名, 类似 self,不过很多人使用 cls 作为变量名字

 

 

 

静态方法和类方法结合例子: 早期没有引入函数装饰符时

 

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) # 将方法转换为类方法

 

执行:

>>> 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()             #  通过实例对象调用类方法
calling class method foo() foo() is part of class: TestClassMethod

 

注意:如果执行在文件中用print打印则会出现如下结果:

#!/usr/bin/env python
#coding:utf8

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)  # 将方法转换为类方法

tsm = TestStaticMethod()
print TestStaticMethod.foo()  #通过类对象本身调用静态方法
print tsm.foo()      # 通过实例对象调用静态方法


tcm = TestClassMethod()
print TestClassMethod.foo()   #通过类对象本身调用类方法
print tcm.foo()     #  通过实例对象调用类方法

 

执行结果:

calling static method foo()
None
calling static method foo()
None
calling class method foo()
foo() is part of class: TestClassMethod
None
calling class method foo()
foo() is part of class: TestClassMethod
None

因为在python函数中,如果没有return语句,会自动返回NONE,如果有return语句,但是return后面没有接表达式或者值的话也是返回NONE

 

优化代码:

#!/usr/bin/env python
#coding:utf8



class TestStaticMethod:
    def foo():
        return 'calling static method foo()'
    foo = staticmethod(foo)  #将方法转换为静态方法


class TestClassMethod:
    def foo(cls):
        print  'calling class method foo()'
        return 'foo() is part of class:', cls.__name__
    foo = classmethod(foo)  # 将方法转换为类方法

tsm = TestStaticMethod()
print TestStaticMethod.foo()  #通过类对象本身调用静态方法
print tsm.foo()      # 通过实例对象调用静态方法


tcm = TestClassMethod()
print TestClassMethod.foo()   #通过类对象本身调用类方法
print tcm.foo()     #  通过实例对象调用类方法

 

执行结果:

calling static method foo()
calling static method foo()
calling class method foo()
('foo() is part of class:', 'TestClassMethod')
calling class method foo()
('foo() is part of class:', 'TestClassMethod')

 

 

使用函数修饰符

1、函数修饰符,一种在 Python2.4 中加入的新特征
2、你可以用它把一个函数应用到另个函数对象上, 而且新函数对象依然绑定在原来的变量。
3、我们正是需要它来整理语法。通过使用 decorators,我们可以避免像上面那样的重新赋值

 

#!/usr/bin/env python
#coding:utf8

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.__name__
tsm = TestStaticMethod()
TestStaticMethod.foo()  #通过类对象本身调用静态方法
tsm.foo()      # 通过实例对象调用静态方法


tcm = TestClassMethod()
TestClassMethod.foo()   #通过类对象本身调用类方法
tcm.foo()     #  通过实例对象调用类方法

 

执行结果:

calling static method foo()
calling static method foo()
calling class method foo()
foo() is part of class: TestClassMethod
calling class method foo()
foo() is part of class: TestClassMethod

 

 

类方法

1、由类调用

2、第一个参数必须是类对象,一般以cls作为第一个参数

3、能够通过实例对象和类对象去访问

 

#!/usr/bin/env pythn
#coding:utf-8

class People(object):
country = 'china'

#类方法,用classmethod来进行修饰
@classmethod
def getCountry(cls):
return cls.country

p = People()
print p.getCountry() #可以用过实例对象引用
print People.getCountry() #可以通过类对象引用
 

 

执行结果:

china
china

类方法还有一个用途就是可以对类属性进行修改:

#!/usr/bin/env python
#coding:utf-8

class People(object):
country = 'china'

#类方法,用classmethod来进行修饰
@classmethod
def getCountry(cls):
return cls.country

@classmethod
def setCountry(cls,country):
cls.country = country


p = People()
print p.getCountry() #可以用过实例对象引用
print People.getCountry() #可以通过类对象引用

p.setCountry('janpan')

print p.getCountry()
print People.getCountry()
 

执行结果:

china
china
janpan
janpan

 

静态方法

需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数

 

#!/usr/bin/env python
#coding:utf-8

class People(object):
    country = 'china'

    @staticmethod
    #静态方法
    def getCountry():
        return People.country


print People.getCountry()

执行结果:

china

 

总结

1、从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;

2、实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。

3、静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用

 

 

下面看一下例子:

 

#!/usr/bin/env python
#coding:utf8

class Foo(object):
    '''类三种方法语法形式'''

    # 在类中定义普通方法,在定义普通方法的时候,必须添加self
    def instance_method(self):
        print "是类{}的实例方法,只能被实例对象调用".format(Foo)

    # 在类中定义静态方法,在定义静态方法的时候,不需要传递任何类的东西
    @staticmethod
    def static_method():
        print("是静态方法")

    # 在类中定义类方法,在定义类方法的时候,需要传递参数cls  cls即为类本身
    @classmethod
    def class_method(cls):
        print("是类方法")


foo = Foo()
foo.instance_method()
foo.class_method()
foo.static_method()
print "---------------"
Foo.static_method()
Foo.class_method()

 

 

 

 可以看出:

 

1.实例方法只能被实例对象调用;静态方法(由@staticmethod装饰的方法)、类方法(由@classmethod装饰的方法),可以被类或类的实例对象调用。
  实例方法,第一个参数必须要默认传实例对象,一般习惯用self。对象方法中有self参数,类方法有cls参数,静态方法是不需要这些附加参数
2.静态方法(@staticmethod):即静态方法,静态方法是一类特殊的方法,有时候你可能需要填写一个属于这个类的方法,但是这些代码完全不会使用到实例对象本身。
 

  当一个函数逻辑上属于一个类又不依赖与类的属性的时候,可以使用staticmethod

  使用staticmethod可以避免每次使用的时都会创建一个对象的开销。

  staticmethod可以使用类和类的实例调用。但是不依赖于类和类的实例的状态。



3.类方法(@classmethod):即类方法,类方法不是绑定到对象上,而是绑定在类上的方法,它更关注于从类中调用方法,而不是从实例中调用方法,如构造重载;

    classmethod是类对象与函数的结合。

    可以使用类和类的实例调用,但是都是将类作为隐含参数传递过去。

    使用类来调用classmethod可以避免将类实例化的开销



4.成员函数:实例的方法,只能通过实例进行调用;

 

 

 

 

 

 

类方法与静态方法说明

 

  1:self表示为类型为类的object,而cls表示为类也就是class

  2:在定义普通方法的时候,需要的是参数self,也就是把类的实例作为参数传递给方法,如果不写self的时候,会发现报错TypeError错误,表示传递的参数多了,
    其实也就是调用方法的时候,将实例作为参数传递了,在使用普通方法的时候,使用的是实例来调用方法,不能使用类来调用方法,没有实例,那么方法将无法调用。   3:在定义静态方法的时候,和模块中的方法没有什么不同,最大的不同就是在于静态方法在类的命名空间之间,而且在声明静态方法的时候,
    使用的标记为@staticmethod,表示为静态方法,在你用静态方法的时候,可以使用类名或者是实例名来进行调用,一般使用类名来调用   4:静态方法主要是用来放一些方法的,方法的逻辑属于类,但是有何类本身没有什么交互,从而形成了静态方法,主要是让静态方法放在此类的名称空间之内,
    从而能够更加有组织性。   5:在定义类方法的时候,传递的参数为cls.表示为类,此写法也可以变,但是一般写为cls。类的方法调用可以使用类,也可以使用实例,一般情况使用的是类。   6:在重载调用父类方法的时候,最好是使用super来进行调用父类的方法。静态方法主要用来存放逻辑性的代码,基本在静态方法中,不会涉及到类的方法和类的参数。
    类方法是在传递参数的时候,传递的是类的参数,参数是必须在cls中进行隐身穿   7:python中实现静态方法和类方法都是依赖python的修饰器来实现的。静态方法是staticmethod,类方法是classmethod。

 

posted @ 2019-06-18 23:52  钟桂耀  阅读(121)  评论(0编辑  收藏  举报