美文网首页
python类的类方法,静态方法,属性方法,普通方法的实现及区别

python类的类方法,静态方法,属性方法,普通方法的实现及区别

作者: hugoren | 来源:发表于2020-02-18 11:49 被阅读0次

    先看例子

    class T:
    
        def test_1(self):
            print("test_1")
    
        @property
        def test_2(self):
            print("property")
    
        @classmethod
        def test_3(cls):
            print("cls")
    
        @staticmethod
        def test_4():
            print("static")
    
    t = T()
    t.test_1()
    t.test_2
    t.test_3()
    T.test_3()
    t.test_4()
    T.test_4()
    

    概念上的区别

    实例方法

    定义:第一个参数必须是实例对象,该参数名一般约定为“self”,通过它来传递实例的属性和方法(也可以传类的属性和方法);
    
    调用:只能由实例对象调用。
    

    类方法

    定义:使用装饰器@classmethod。第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法(不能传实例的属性和方法);
    
    调用:实例对象和类对象都可以调用。
    

    静态方法

    定义:使用装饰器@staticmethod。参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法;
    
    调用:实例对象和类对象都可以调用。
    

    什么场景下使用

    • 注重安全和性能的,优先考虑staticmethod
    • 当作属性来使用的,使用property
    • 默认使用python实例的,使用普通方法
    • 既可以使用类或实例来调用的,使用类方法

    底层的实例

    property的实现

    class Property:
    
        # 装饰器类的语法和装饰器方法类似,
        # @property等价于roperty(...)
        # 入参体现在初始化方法中
        def __init__(self, func):
            self.__name__ = func.__name__
            self.getF = func
            self.setF = None
            pass
    
        def setter(self, func):
            self.setF = func
            return self
    
        def __set__(self, instance, value):
            self.setF(instance, value)
            pass
    
        def __get__(self, instance, owner):
            return self.getF(instance)
    
    class A(object):
        
        # 利用roperty像property一样定义属性
        # 这里等价于name = roperty(name)
        # 利用装饰器语法,name被赋值为roperty的实例
        @roperty
        def name(self):
            print('get name1')
            return self.__name
            
        # 由于name被赋值为roperty的实例
        # 为了演示上的区分,方法名为name1,实际开发中用name即可
        # 以下等价于name1 = name.setter(name1)
        @name.setter
        def name1(self, n):
            print('set name')
            self.__name = n
    
    a = A()
    
    # 值得注意的是,经过装饰器语法后A.name已经是roperty对象(这里roperty对象既是一个装饰器又是一个描述器)
    # 根据描述器的特性,a.name赋值会触发描述器的__set__方法,继而调用name属性定义的set方法
    a.name = 'name1111'
    
    # 根据描述器的特性,a.name读取会触发描述器的__get__方法,继而调用name属性定义的get方法
    print(a.name)
    

    classmethod 与staticmethod 的实现

    class classmethod1(object):
    
        def __init__(self, func):
            self.sf = func
    
        def __get__(self, instance, owner):
            return lambda *args, **kwargs: self.sf(owner, *args, **kwargs)
    
    class staticmethod1(object):
    
        def __init__(self, func):
            self.sf = func
    
        def __get__(self, instance, owner):
            return lambda *args, **kwargs: self.sf(*args, **kwargs)
    
    class T(object):
    
        def name(self):
            print('instance.name')
    
        @classmethod1
        def className(cls):
            print('{}.name'.format(cls))
    
        @staticmethod1
        def staticName(ipt):
            print('{}.name'.format(ipt))
    
    

    相关文章

      网友评论

          本文标题:python类的类方法,静态方法,属性方法,普通方法的实现及区别

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