zoukankan      html  css  js  c++  java
  • 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。
  • 相关阅读:
    RAD Studio XE2/XE3 官方 ISO 下载地址 (20120905更新)
    delphi调用webservice接口时返回result element expected的解决办法
    delphi 线程使用
    App数据格式之解析Json
    android 改变文字的大小和字体
    [最新]Visual Assist X 破解版下载(10.7.1929_Patched)
    [解决]Win7 操作系统不能安装VMware
    android 获取已安装程序列表
    unidac 执行Execute后取得受影响行数。
    android 获取所有传感器数据
  • 原文地址:https://www.cnblogs.com/zhongguiyao/p/11048696.html
Copyright © 2011-2022 走看看