python实例、类、静态方法

方法是使用属性表示法调用的函数。

实例方法

实例方法第一个参数需要为实例本身(self),需要将类实例化后调用,如果使用类直接调用实例方法,需要显式地将实例作为参数传入。

如果通过实例访问方法(类名称空间中定义的函数),则会得到一个特殊对象:绑定方法(也称为实例方法)对象。
调用时,它会将self参数添加到参数列表中。
绑定方法有两个特殊的只读属性:m . self是方法操作的对象,m . func是实现该方法的函数。调用m(arg-1,arg-2,…,arg-n)完全等同于调用m . func (m . self ,arg-1,arg-2,…,arg-n)。

最左侧传入的参数,是实例本身。

class ClassA(object):    def func_a(self):        print('Hello Python')if __name__ == '__main__':    # 使用实例调用实例方法    ca = ClassA()    ca.func_a()    # 如果使用类直接调用实例方法,需要显式地将实例作为参数传入    ClassA.func_a(ca)

与函数对象一样,绑定的方法对象支持获取任意属性。但是,由于方法属性实际存储在底层函数对象(meth . func)中,因此不允许在绑定方法上设置方法属性。
尝试设置方法属性会导致引发TypeError。要设置方法属性,您需要在底层函数对象上显式设置它:

class C:    def method(self):        passc = C()c.method.__func__.whoami = 'my name is c'

类方法

通常情况,类方法使用@classmethod装饰器来声明
类方法传入第一个参数为cls,是类本身。
类方法可以通过类或实例对象直接调用,但不管哪种方式,最左侧参数传入的都是类对象本身。

class ClassA(object):    @classmethod    def func_a(cls):        print(type(cls), cls)if __name__ == "__main__":    ClassA.func_a()    ca = ClassA()    ca.func_a()

运行结果如下:

  

如果有类的继承,类方法获得的是派送类对象。

class BaseA(object):    @classmethod    def func_a(cls):        print(type(cls), cls)class BaseB(object):    passclass ClassA(BaseA, BaseB):    passif __name__ == '__main__':    ClassA.func_a()    ca = ClassA()    ca.func_a()

代码中ClassA继承自BaseA、BaseB,在调用类方法时,虽然类方法是从BaseA继承而来,但是传入func_a的cls函数实际上是ClassA。

所以,在某些时候,需要明确调用类属性时,不要使用类方法传入的cls参数,因为它传入的是类树中最底层的类,不一定符合设计初衷。可以直接通过类名访问类属性。

静态方法

静态方法无需self与cls参数。使用@staticmethod装饰器来声明。
在调用过程中,无需将类实例化。

class ClassA(object):    @staticmethod    def func_a():        print('Hello Python')if __name__ == '__main__':    ClassA.func_a()    ca = ClassA()    ca.func_a()

注意:在Python 2 中,如果一个类的方法不需要self参数,必须声明为静态方法,即加上@staticmethod装饰器,从而不带实例调用它。而在Python 3中,如果一个类的方法不需要self参数,不再需要声明为静态方法,但是这样的话只能通过类去调用这个方法,如果使用实例调用这个方法会引发异常。

参考文献

Was this helpful?

0 / 0

发表回复 0