面向对象微讲解(四)

面向对象微讲解(四)

面向对象双下方法

1.__str__:对象被执行打印(print、前端展示)操作的时候自动触发,该方法必须返回字符串类型的数据,很多时候用来更
加精准的描述对象。
class Student:
    def __init__(self,name):
        self.name = name

    def __str__(self):
        print('什么时候打印我')
        return '这是一个对象%s'%self.name

obj = Student('oscar')
print(obj)  # 当我们执行打印语句的时候,__str__会自动执行
2.__del__:对象被执行(被动、主动)删除操作之后自己执行。(相当于我们只讲过的垃圾回收机制)
class Student:
    def __init__(self,name):
        self.name = name

    def __del__(self):
        print('什么时候打印我')


obj = Student('oscar')
# del obj  # 这是主动执行,可以指定执行的地方
print(obj.name)  # 先输出的打印语句,然后自动执行的__del__方法
3.__getattr__:对象查找不存在的名字的时候自动触发。
class Student:
    def __init__(self,name):
        self.name = name

    def __getattr__(self, item):
        print('什么时候打印我')
        return '%s不存在'%item


obj = Student('oscar')
print(obj.name)  # 打印oscar,不执行__getattr__方法
print(obj.age)  # 执行__getattr__方法
4.__getattribute__:只要对象查找名字,无论名字是否存在都会执行该方法,如果类中有__getattribute__方法就不会
执行__getattr__方法。
class Student:
    def __init__(self,name):
        self.name = name
    def __getattribute__(self, item):
        print('无论什么时候打印我')
        return item

obj = Student('oscar')
print(obj.name)  # 都会执行打印,不会报错
print(obj.age)  # 都会执行打印,不会报错
5.__setattr__:在对象执行添加属性操作的时候触发。
class Student:

    def __setattr__(self, key, value):
        print('你添加了键值对k:%s v:%s'%(key,value))


obj = Student()
obj.name = 'oscar'  # 执行这一句的时候自动执行__setattr__方法
6.__call__:对象被加括号调用的时候自动执行。
class Student:
    def __init__(self,name):
        self.name = name
    def __call__(self, *args, **kwargs):
        print('什么时候打印我')
        return 123


obj = Student('oscar')
print(obj())  # 对象是不能直接加括号调用的,加了__call__方法就可以,返回值后面跟什么就返回什么
7.__enter__:对象被执行with语法的时候自动执行,该方法返回什么as后面的变量名就会得到什么。
__exit__:对象被执行with语法结束的时候自动执行。
class Student:
    def __init__(self,name):
        self.name = name
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

obj = Student('oscar')
with obj as f:
    res = f.name

print(res)  # oscar

元类

1.元类简介

1.元类即原始的类,产生类的类。
2.学习元类的目的:元类能够控制类的创建,也就意味着我们可以高度定制类的行为。
# print(type(123))  # <class 'int'>
# print(type([123,11,'oscar']))  #<class 'list'>
# print(type('oscar'))  # <class 'str'>
'''我们type关键字查看数据类型的时候,会返回数据的类型,
我们会发现前面有一个class,实质数据类型也是一个类,那我们
能不能type一个类,来看看产生类的类是什么
'''
class Student:
    pass
print(type(Student))  # <class 'type'>
class Teacher(Student):
    pass
print(type(Teacher))  # <class 'type'>
'''
我们会发现都是type,所以type就是所有类默认的元类
'''

2.产生类的两种变现形式

1.class关键字
	class 类名:
        类体代码
2.type元类
	# type(类名,父类,类的名称空间)
	res = type('Student',(),{})
	print(res)  # <class 		'__main__.Student'>

3.元类的基本使用

1.元类是不能够通过继承的方式直接指定的,需要通过关键字'metaclass'参数的形式修改。
# 修改元类的方法,创建类的时候首字母必须大写,否则就报错
class Student(type):
    def __init__(cls,cls_name,cls_bases,cls_dict):
        if not cls_name.istitle():
            raise Exception('创建类的时候类名首字母必须大写!!')
        super().__init__(cls_name,cls_bases,cls_dict)
        
class Teacher(metaclass=Student):  # 通过关键字'metaclass'参数的形式修改。
    name = 'oscar'
# class teacher(metaclass=Student):
#     name = 'oscar'

4.元类进阶操作

1.我们之前讲__call__方法的时候,对象加括号会自动执行产生该对象的类里面的__call__,并且该方法返回什么对象加
括号就会得到什么,那我们就可以推导类加括号会执行元类的里面的__call__,该方法返回什么类加括号就会得到什么。
2.类里面的__init__和元类的__call__执行的先后顺序。
class Student(type):
    def __call__(self, *args, **kwargs):
        print('我是__call__')
        super().__call__(*args, **kwargs)

class Teacher(metaclass=Student):
    def __init__(self,name):
        print('我是__init__')
        self.name = name
obj = Teacher('oscar')
'''
我是__call__
我是__init__
先执性元类的__call__方法,然后在执行类的__init__方法
'''
3.定制对象的产生过程
class Student(type):
    def __call__(self, *args, **kwargs):
        if args:
            raise Exception('必须全部采用关键字参数')
        super().__call__(*args, **kwargs)

class Teacher(metaclass=Student):
    def __init__(self,name):
        self.name = name
obj = Teacher(name = 'oscar')
'''
如果你想高度定制类的产生过程:就编写元类里面的__init__方法。
如果你想高度定制对象的产生过程:就编写元类里面的__call__方法。
'''

5.双下new方法

__new__用于产生空对象(类)
__init__用于实例化对象(类)
# 并不是所有的地方都可以直接调用__new__,该方法过于底层。
1.如果是在元类的__new__里面可以直接调用
class Student(type):
    def __call__(cls, *args, **kwargs):
        obj = type.__new__(cls,*args,**kwargs)
        return obj
2.如果在元类的__call__里面需要间接调用
class Student(type):
    def __call__(self, *args, **kwargs):
        obj = type.__new__(self)  # 创建一个空对象
        self.__init__(obj,*args,**kwargs)  # 让对象去初始化
        return obj

这里是IT小白陆禄绯,欢迎各位大佬的指点!!!


__EOF__

本文作者陆禄绯
本文链接https://www.cnblogs.com/pyqsy/p/16131474.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   陆禄绯  阅读(54)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
点击右上角即可分享
微信分享提示