python中的内置装饰器@classmethod,@staticmethod和@property

一 类方法classmethod

在python中,classmethod是内置的装饰器之一,它的作用如下

  • 声明一个方法是类方法,可以不用创建实例对象就调用类方法,调用方式:类名.方法名,其中方法的参数self变成cls,cls的作用同self一样。

无classmethod声明

#无classmethod
class my_class():

    def __init__(self):
        pass

    def func1(self):
        print("this is func1")

    def func2(self):
        print("this is func2")

#不创建实例对象,直接调用方法
my_class.func1()
my_class.func2()

>>>
Traceback (most recent call last):
  File "C:/Users/admin/python-learning/python学习文件/python基础/CSDN.py", line 21, in <module>
    my_class.func1()
TypeError: func1() missing 1 required positional argument: 'self'

可以看到,在没有用装饰器classmethod的时候,不创建实例化对象就调用类方法是会报错的。

有classmethod装饰器

#有classmethod
class my_class():

    def __init__(self):
        pass

    @classmethod
    def func1(cls):
        print("this is func1")

    def func2(self):
        print("this is func2")

#func1有classmethod装饰,func2没有
my_class.func1()
my_class.func2()

>>>
Traceback (most recent call last):
  File "C:/Users/admin/python-learning/python学习文件/python基础/CSDN.py", line 23, in <module>
    my_class.func2()
TypeError: func2() missing 1 required positional argument: 'self'
this is func1

上面的func1使用了classmethod进行装饰,就可以不用创建实例对象直接进行类名.类方法调用;而func2没有使用classmethod进行声明,所以仍然会报错。

二 静态方法staticmethod

同样的,staticmethod也是python内置的装饰器之一,它的作用如下

  • 声明一个方法是一个静态方法,可以不用创建实例对象就调用类方法,调用式:类名.方法名,其中方法的参数self可以去掉。
#classmethod, staticmethod
class my_class():

    def __init__(self):
        pass

    @classmethod
    def func1(cls):
        print("this is func1")

    @staticmethod
    def func2():
        print("this is func2")

    def func3(self):
        print("this is func3")

#func1有classmethod装饰,func2有staticmethod,func3没有进行任何装饰
my_class.func1()
my_class.func2()
my_class.func3()

this is func1
this is func2
Traceback (most recent call last):
  File "C:/Users/admin/python-learning/python学习文件/python基础/CSDN.py", line 28, in <module>
    my_class.func3()
TypeError: func3() missing 1 required positional argument: 'self'

上面对func1用了classmethod进行声明是一个类方法,func2staticmethod声明是一个静态方法,它们都可以用 类名.方法名 进行直接调用,而不用创建实例对象;但是func3没有进行任何装饰,就不能直接用 类名.方法名 进行调用,所有还是会报错。

从上面可以看出方法用classmethodstaticmethod进行装饰后,都不用创建实例对象就可以直接调用类方法。但它们还是有些区别的,如下

  • classmethod是需要cls参数的,cls和self一样,代表类本身,但是 cls不能调用实例对象的属性,即不能调用def __ init __ 下面的属性。可以通过 cls.类属性 或 cls.类方法 来调用类的属性和方法
  • staticmethod不需要self和cls参数,它注重的是类的静态变量,跟类的实例化对象没有关系,所以它 也不能调用类实例化对象的属性,即def __ init __ 下面的属性,而且只能通过 类名.类属性,类名.类方法 来调用类的属性和方法

下面用个例子说明

#classmethod, staticmethod
class my_class():

    __pwd = 123456

    def __init__(self):
        self.name = '老六'

    @classmethod
    def func1(cls):
        #不能调用实例对象的属性,可以通过cls调用类的属性
        print("this is func1")
        print(cls.__pwd)

    @staticmethod
    def func2():
        #不能调用实例对象的属性,只能调用类的属性
        print("this is func2")
        print(my_class.__pwd)

    def func3(self):
        #可以调用实例对象的属性,也可以调用类的属性
        print("this is func3")
        print(self.__pwd)
        print(self.name)

#func1有classmethod装饰,func2有staticmethod,func3没有进行任何装饰
my_class.func1()
my_class.func2()
#需要创建实例对象才能调用func3
my_class().func3()

结果如下

>>>
this is func1
123456
this is func2
123456
this is func3
123456
老六

三 property

python中property一般有两个作用,如下

  • 作为装饰器,@property 将类的方法转为只读的类属性
  • property 重新实现一个属性的 getter 和 setter 方法

property作为装饰器使用,如下

#property
class my_class():

    def __init__(self):
        pass

    @property
    def func1(self):
        print("this is func1")

    def func2(self):
        print("this is func2")


#有@property,转换成类属性
my_class().func1
#无@property,不会转换成类属性
print(my_class().func2)

结果

>>>
this is func1
<bound method my_class.func2 of <__main__.my_class object at 0x0000022E361C7148>>

可以看到,func1@property 进行了装饰,转换成了类属性,就可以像调用类属性一样调用该方法,而func2没有进行装饰,因而不能像调用类属性一样调用该方法。

下面@property 重新实现一个私有属性的 getter 和 setter 方法

class E():
    __name = '张三'

    def __init__(self):
        self.__age = 23
        self.__luange = 'python'

    def __method(self):
        print("我叫{},今年{}岁,我喜欢{}。".format(self.__name, self.__age, self.__luange))

    @property
    def name(self):
        return self.__name
        
    @name.setter
    def name(self, name):
        self.__name = name

if __name__ == '__main__':
    e = E()
    #访问
    print(e.name)
    #修改
    print("修改前:", e.name)
    e.name = '隔壁老王'
    print("修改后:", e.name)

输出结果

>>>
张三
修改前: 张三
修改后: 隔壁老王

上面是首先把name方法送给propert装饰器进行装饰,然后调用装饰后的setter方法,即可实现对私有属性进行修改。

property更多的是用在对类私有属性方面的保护,更详细的可以参考这篇文章:Python面向对象之封装(三)

  • 5
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值