面向对象 类的三个装饰器

1. property

1.1 概念

作用:将一个方法伪装成属性

​  如下,定义一个Student类,类中有一个计算年龄的方法,在最后调用的时候,需要通过tom.age()的方式来获取对象的年龄;age为名词,理论上用属性来表示更为合适,这种调用方式明显能看出age是一个方法

import time

class Student:
    def __init__(self,name,birth):
        self.name = name
        self.birth = birth

    def age(self):
        return time.localtime().tm_year - self.birth

tom = Student('tom',1992)
print(tom.age())	# 28

@property来装饰age方法,将其伪装成一个属性,此时,就可以通过tom.age直接调用

import time

class Student:
    def __init__(self,name,birth):
        self.name = name
        self.birth = birth

    @property
    def age(self):
        return time.localtime().tm_year - self.birth

tom = Student('tom',1992)
print(tom.age)	# 28

1.2 示例

class Circle:
    def __init__(self,r):
        self.r = r
    @property
    def area(self):
        return 3.14*self.r**2
    @property
    def perimeter(self):
        return 2*3.14*self.r

c1 = Circle(3)
print(c1.perimeter) # 18.84
print(c1.area)  # 28.26

1.3 为什么要用property

​  将一个类的函数定义成proerty特性以后(即加property装饰器),对象再通过obj.name去调用的时候,根本无法察觉自己的name是执行了一个函数然后计算出来的,这种特性的使用方式遵循了统一访问的原则


2. staticmethod

2.1 概念

​  @staticmethod装饰器,可以声明一个类内部的方法为静态方法,不必传任何默认的参数(如self),当然也可传入需要的参数,就相当于一个普通的函数一样;且可以直接通过类名来调用该方法

​  常用于,在实例化之前就想要执行该函数/方法的情况

​  静态方法:类里面不必实例化就可以调用的方法,不需要传递对象作为参数,就定义这个方法为静态方法

2.2 示例

​  如下例,login为Student类中的一个方法,按照常理,想要调用login方法就必须先要实例化一个对象,但是要实例化一个对象就必须先有有一个用户先输入名字,可是想输入名字就得先执行登录方法,这是一个死循环

​  通过staticmethod装饰器,login定义为静态方法,不用传self参数,也就是说不用实例化也可执行。这样就可以直接通过类Student.login()来调用该方法

class Student:
    def __init__(self,name):
        self.name = name

    @staticmethod		# 声明login方法是一个静态方法,不必传任何默认的参数,包括self
    def login(message):
        print('登录程序',message)
        username = input('username >>>')
        stu = Student(username)
        return stu

obj = Student.login('forTest')	# 用类名可以直接调用这个方法
print(obj.__dict__)		# 从输出可以看出,obj是一个实例化后的Student对象

'''输出内容
登录程序 forTest
username >>>tom
{'name': 'tom'}
'''

3. classmethod

3.1 概念

​  @classmethod装饰器,可以声明一个类内部的方法为类方法,默认传参数cls,表示当前所在的类名(本质上是传入的本类的内存地址),且可以用类名直接调用该方法。

​  常用于在类的一个方法(函数)里会用到自己的类名,就可以通过classmethod定义为类方法

​  类方法:默认传入参数cls,表示当前所在的类名

3.2 示例

​  将login方法定义为类方法后,传入cls参数,内部在实例化的过程中就可以直接通过cls(name)的方式来实例化了,且不管本类的类名如何变化,其均代表本类(本质上传入的是本类的内存地址),执行不会受到影响

class Student:
    def __init__(self,name):
        self.name = name

    @classmethod		# 装饰当前这个方法为一个类方法,默认传参数cls,表示当前所在的类名
    def login(cls,message):
        print('登录程序',message)
        username = input('username >>>')
        stu = cls(username)		# 直接用cls()的方法实例化
        return stu

obj = Student.login('forTest')
print(obj.__dict__)

'''输出
登录程序 forTest
username >>>jack
{'name': 'jack'}
'''

将类名由Student改为Manager,输出结果不变

class Manager:
    def __init__(self,name):
        self.name = name

    @classmethod
    def login(cls,message):
        print('登录程序',message)
        username = input('username >>>')
        stu = cls(username)
        return stu

obj = Manager.login('forTest')
print(obj.__dict__)

'''输出
登录程序 forTest
username >>>jack
{'name': 'jack'}
'''

4. 总结

class A:

    # 方法在当前类中,并用到了实例化后的对象也就是self,那么就用实例方法
    def func1(self): pass   # 实例方法,self作为默认参数,需要用实例化后的对象来调用

    # 方法在当前类中,且未用到实例,但是用到了类名,那么就用类方法
    @classmethod
    def func2(cls): pass    # 类方法,cls作为默认参数,可以用类名来调用

    # 方法在当前类中,且即未用到与实例和类相关的内容,可以用静态方法
    @staticmethod
    def func3(): pass   # 静态方法,没有默认参数,可以用类名来调用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值