美文网首页
Python 实例方法、类方法和静态方法(转)

Python 实例方法、类方法和静态方法(转)

作者: RayRaymond | 来源:发表于2020-05-23 18:05 被阅读0次

    实例方法

    class Kls(object):
        def __init__(self, data):
            self.data = data
    
        def printd(self):
            print(self.data)
    
    
    ik1 = Kls('leo')
    ik2 = Kls('lee')
    ik1.printd()
    ik2.printd()
    # leo
    # lee
    

    实例ik1会传递给self参数,这样self参数就可以引用当前正在调用实例方法的实例。

    类方法

    Python 的类方法采用装饰器@classmethod来定义

    class Kls(object):
        num_inst = 0
    
        def __init__(self):
            Kls.num_inst = Kls.num_inst + 1
    
        @classmethod
        def get_no_of_instance(cls):
            return cls.num_inst
    
    
    ik1 = Kls()
    ik2 = Kls()
    
    print(ik1.get_no_of_instance())
    print(Kls.get_no_of_instance())
    # 2
    # 2
    

    在上述例子中,我们需要统计类Kls实例的个数,因此定义了一个类变量num_inst来存放实例个数。通过装饰器@classmethod的使用,方法get_no_of_instance被定义成一个类方法。在调用类方法时,Python 会将类(class Kls)传递给cls,这样在get_no_of_instance内部就可以引用类变量num_inst
    由于在调用类方法时,只需要将类型本身传递给类方法,因此,既可以通过类也可以通过实例来调用类方法。

    class A(object):
    
        # 属性默认为类属性(可以给直接被类本身调用)
        num = "类属性"
    
        # 实例化方法(必须实例化类之后才能被调用)
        def func1(self): # self : 表示实例化类后的地址id
            print("func1")
            print(self)
    
        # 类方法(不需要实例化类就可以被类本身调用)
        @classmethod
        def func2(cls):  # cls : 表示没用被实例化的类本身
            print("func2")
            print(cls)
            print(cls.num)
            cls().func1()
    
        # 不传递传递默认self参数的方法(该方法也是可以直接被类调用的,但是这样做不标准)
        def func3():
            print("func3")
            print(A.num) # 属性是可以直接用类本身调用的
        
    # A.func1() 这样调用是会报错:因为func1()调用时需要默认传递实例化类后的地址id参数,如果不实例化类是无法调用的
    A.func2()
    A.func3()
    ##########################################################################################
    # func2
    # <class '__main__.A'>
    # 类属性
    # func1
    # <__main__.A object at 0x000001F088567D60>
    # func3
    # 类属性
    

    静态方法

    在开发中,我们常常需要定义一些方法,这些方法跟类有关,但在实现时并不需要引用类或者实例,

    例如,设置环境变量,修改另一个类的变量等。这个时候,我们可以使用静态方法。

    Python 使用装饰器@staticmethod来定义一个静态方法。

    IND = 'ON'
    
    
    class Kls(object):
        def __init__(self, data):
            self.data = data
    
        @staticmethod
        def checkind():
            return IND == 'ON'
    
        def do_reset(self):
            if self.checkind():
                print('Reset done for: %s' % self.data)
    
        def set_db(self):
            if self.checkind():
                print('DB connection made for: %s' % self.data)
    
    
    ik1 = Kls(24)
    ik1.do_reset()
    ik1.set_db()
    ########################################################################
    # Reset done for: 24
    # DB connection made for: 24
    
    

    区别概括

    class Kls(object):
        # 实例方法
        def foo(self, x):
            print('executing foo(%s,%s)' % (self, x))
    
        # 类方法
        @classmethod
        def class_foo(cls,x):
            print('executing class_foo(%s,%s)' % (cls,x))
    
        # 静态方法
        @staticmethod
        def static_foo(x):
            print('executing static_foo(%s)' % x)
    
    
    ik = Kls()
    
    # 实例方法
    ik.foo(1)
    print(ik.foo)
    print('==========================================')
    # executing foo(<__main__.Kls object at 0x00000279F1087B80>,1)
    # <bound method Kls.foo of <__main__.Kls object at 0x00000279F1087B80>>
    # ==========================================
    
    # 类方法
    ik.class_foo(1)
    Kls.class_foo(1)
    print(ik.class_foo)
    print('==========================================')
    # executing class_foo(<class '__main__.Kls'>,1)
    # executing class_foo(<class '__main__.Kls'>,1)
    # <bound method Kls.class_foo of <class '__main__.Kls'>>
    # ==========================================
    
    # 静态方法
    ik.static_foo(1)
    Kls.static_foo('hi')
    print(ik.static_foo)
    # executing static_foo(1)
    # executing static_foo(hi)
    # <function Kls.static_foo at 0x00000279F109D3A0>
    
    • 实例方法

      调用时会把实例ik作为第一个参数传递给self参数。因此,调用ik.foo(1)时输出了实例ik的地址。

    • 类方法

      调用时会把类Kls作为第一个参数传递给cls参数。因此,调用ik.class_foo(1)时输出了Kls类型信息。

    • 静态方法

      调用时并不需要传递类或者实例。其实,静态方法很像我们在类外定义的函数,只不过静态方法可以通过类或者实例来调用而已。

    值得注意的是,在上述例子中,foo只是个函数,但当调用ik.foo的时候我们得到的是一个已经跟实例ik绑定的函数。

    • 调用foo时需要两个参数,但调用ik.foo时只需要一个参数。fooik进行了绑定. 当我们打印ik.foo时,会看到以下输出:
    <bound method Kls.foo of <__main__.Kls object at 0x00000279F1087B80>>
    
    • 调用ik.class_foo时,由于class_foo是类方法,因此,class_fooKls进行了绑定(而不是跟ik绑定)。当我们打印ik.class_foo时,输出:
     <bound method Kls.class_foo of <class '__main__.Kls'>>
    
    • 调用ik.static_foo时,静态方法并不会与类或者实例绑定,因此,打印ik.static_foo(或者Kls.static_foo)时输出:
    <function Kls.static_foo at 0x00000279F109D3A0>
    

    概括来说,是否与类或者实例进行绑定,这就是实例方法,类方法,静态方法的区别

    Reference

    [1] Python 实例方法、类方法和静态方法

    相关文章

      网友评论

          本文标题:Python 实例方法、类方法和静态方法(转)

          本文链接:https://www.haomeiwen.com/subject/ohylahtx.html