面向对象微讲解(四)
面向对象微讲解(四)
面向对象双下方法
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 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/pyqsy/p/16131474.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统