【Python】类方法、魔术方法、描述符

类方法的分类

对象方法

特征:

  1. 在类中定义的方法,含有self参数
  2. 只能使用对象进行调用
  3. 该方法会把调用的对象传递进来

类方法

特征:

  1. 在类中定义的方法,使用装饰器 @classmethod 进行了装饰
  2. 方法中有cls这个行参。不需要实例化对象,直接使用类进行调用
  3. 会把调用这个方法的类传递进来

绑定类方法

特征:

  1. 在类中定义的方法
  2. 只能使用类进行调用
  3. 不会传递对象或者类进来

静态方法

特征:

  1. 在类中定义的方法,使用了 装饰器 @staticmethod进行了装饰
  2. 可以使用对象或者类进行调用
  3. 不会传递对象或者类进来

魔术方法

__init__ 初始化方法

  • 触发机制:当类实例化之后就会触发的方法
  • 作用: 为当前创建的对象完成一些初始化的操作,比如:成员属性的赋值,方法的调用,打开或创建一些资源
  • 参数: self,接受当前对象,其它参数根据需求进行定义即可
  • 返回值: 无

__new__ 构造方法

  • 触发机制:类实例化时自动触发(在__init__之前触发)
  • 作用:管理控制对象创建的过程
  • 参数:一个cls接收当前类,其它参数根据初始化方法的参数进行决定
  • 返回值:必须返回object.__new__(cls)进行对象的创建,如果没有返回值,则实例化对象的结果为None
  • 注意事项:__new__方法的参数和__init__方法的参数要保持一致,除了参数cls。应用场景:设计模式中的单例设计模式

__del__析构方法

  • 触发机制:当该类对象被销毁时,自动触发
  • 作用:关闭或释放对象创建时打开或创建的一些资源
  • 参数:self,接受当前的对象
  • 返回值:无

__call__

  • 触发机制:把对象当作函数直接调用时自动触发
  • 作用:一般用于归纳类或对象的操作步骤,方便调用
  • 参数:self接收当前对象,其它参数根据需求确定
  • 返回值:可有可无

__len__

  • 触发机制:当使用len函数去检测当前对象的时候自动触发
  • 作用:可以使用len函数检测当前对象中某个数据的信息
  • 参数:self接收当前对象
  • 返回值:必须有,并且必须是一个整型
  • 注意事项:len要获取什么属性的值,就在返回值中返回哪个属性的长度即可

__str__

  • 触发机制: 当使用str或者print函数对对象进行操作时自动触发
  • 作用:代码对象进行字符串的返回,可以自定义打印的信息
  • 参数:self,接收当前对象
  • 返回值:必须有,而且必须是字符串类型的值

__repr__

  • 触发机制:在使用repr方法对当前对象进行转换时自动触发
  • 作用:可以设置repr函数操作对象的结果
  • 参数:self,接收当前对象
  • 返回值:必须有,而且必须是字符串类型的值
  • 注意:正常情况下,如果没有__str__这个魔术方法,__repr__方法就会代替__str__魔术方法

__bool__

  • 触发机制: 当前使用bool函数转换当前对象时,自动触发;默认情况下,对象会转为True
  • 作用:可以代替对象进行bool类型的转换,可以转换任何数据
  • 参数:self接收对象
  • 返回值: 必须是布尔类型

__getattribute__

  • 触发机制:当访问对象成员时,自动触发,无论当前成员是否存在
  • 作用:可以在获取对象成员时,对数据进行一些处理
  • 参数:一个self接收对象,一个item接收当前访问的成员名称
  • 返回值:可有可无,返回的值就是访问的结果
  • 注意事项:在当前的魔术方法中,禁止对当前对象的成员进行访问,否则会触发递归。如果想要在当前魔术方法中访问对象的成员必须使用object来进行访问,格式:object.__getattribute__(self, item)

__getattr__

  • 触发机制:当访问对象中不存在的成员时,自动触发
  • 作用:防止访问不存在的成员时报错,也可以为不存在的成员进行赋值操作
  • 参数:一个self接收当前对象,一个item接收当前访问的成员名称
  • 返回值:可有可无
  • 注意事项:当存在__getattribute__方法时,会去执行__getattribute__方法。也要注意,不要在当前的方法中再次去访问这个不存在的成员,会触发递归操作

__setattr__

  • 触发机制:当给对象的成员进行赋值操作时会自动触发(包括添加,修改)
  • 作用:可以限制或管理对象成员的添加和修改操作
  • 参数:self接收当前对象,key设置的成员名,val 设置的成员值
  • 返回值:无
  • 注意事项:在当前的魔术方法中禁止给当前对象的成员直接进行赋值操作,会触发递归操作;如果想要给当前对象的成员进行赋值,需要借助object,格式: object.__setattr__(self, key, value)

__delattr__

  • 触发机制:当删除对象成员时自动触发
  • 作用:可以去限制对象成员的删除,还可以删除不存在成员时防止报错
  • 参数:self 接收当前对象,item 删除的成员名称
  • 返回值:无
  • 注意事项:在当前魔术方法中禁止直接删除对象的成员,会触发递归操作;如果想要删除当前对象的成员,那么需要借助 object,格式: object.__delattr__(self, item)

获取类/对象的所属成员

  • Class.__dict__ :获取当前类(Class)的所属成员
  • obj.__dict__ :获取当前对象(obj)的所属成员

获取类/对象的文档信息

  • Class.__doc__:获取当前类(Class)的文档信息
  • obj.__doc__:获取当前对象(obj)的文档信息

获取类名

  • Class.__name__:返回’Class’

获取类所在的文件名称

  • Class.__module__:获取当前类(Class)所在的文件名称,如果是当前文件,显示为__main__

获取类的父类列表

  • Class.__base__:获取当前类(Class)继承的第一个父类
  • Class.__bases__:获取当前类(Class)继承的所有的父类列表

获取类的继承链

  • Class.__mro__:获取当前类(Class)的继承链

描述符

定义

当一个类中,包含了三个魔术方法(__get__, __set__, __delete__)中的一个或多个时,那么这个类就称为描述符类

作用

描述符的作用就是对一个类中的某个成员进行一个详细的管理操作(获取,赋值,删除),描述符属于类,只能定义为类的属性

  • __get__(self, instance, owner)

    • 触发机制:在访问对象成员属性时自动触发(当该成员已经交给描述符管理时)
    • 作用:设置当前属性获取的值
    • 参数:self为描述符对象,instance为被管理成员的类的对象,owner为被管理成员的类
    • 返回值:返回值作为成员属性获取的值
  • __set__(self, instance, value)

    • 触发机制:在设置对象成员属性时自动触发(当该成员已经交给描述符管理时)
    • 作用:对成员的赋值进行管理
    • 参数:self为描述符对象,instance为被管理成员的类的对象,value为要设置的值
    • 返回值:无
  • __delete__(self, instance)

    • 触发机制:在删除对象成员属性时自动触发(当该成员已经交给描述符管理时)
    • 作用:对成员属性的删除进行管理
    • 参数:self描述符对象,instance为被管理成员的类的对象
    • 返回值:无

实例

# 定义一个学生类,需要记录学生的学号,名字,分数,学生的分数只能在0-100范围中
# 如何对分数的合理性进行判断?如果在__init__中进行判断,那只能在类实例化的时候判断一次,之后再进行赋值操作就无法判断了。
# 所以我们定义一个描述符类用于管理分数
class Score:
    def __get__(self, instance, owner):
        return self.__score
    def __set__(self, instance, value):
        if 0 <= value <= 100:
            self.__score = value
        else:
            print('分数不符合要求')

# 使用描述符类代理score分数属性
class Student:
	score = Score()
    def __init__(self, stu_id, name, score):
        self.stu_id = stu_id
        self.name = name
        self.score = score

    def get_info(self):
        info =  f'''
        学生学号: {self.stu_id}
        学生姓名: {self.name}
        学生分数: {self.score}
        '''
        print(info)

# 实例化对象
stu = Student(1011, '张三', 99)
stu.get_info()
stu.score = -20
stu.score = 88
stu.get_info()

输出:
在这里插入图片描述

访问对象成员的顺序

  1. 调用 __getattribute__魔术方法
  2. 调用数据描述符
  3. 调用当前对象的成员
  4. 调用当前类的成员
  5. 调用非数据描述符
  6. 调用父类的成员
  7. 调用__getattr__魔术方法
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值