Python——面向对象(魔法方法、元类)

1|0Python——面向对象(魔法方法、元类)

1|1魔法方法

''' 魔法方法: 类中定义的双下方法都称为魔法方法 不需要人为调用 在特定的条件下回自动触发运行 eg:__init__创建空对象之后自动触发给对象添加独有的数据 ''' # coding:utf-8 # # # class Student: # def __init__(self, name): # self.name = name # print('__init__') # # # obj = Student('HaiMan') # __init__ # # print(obj.name) # HaiMan class Student: ''' 1.__init__ 对象添加独有数据的时候自动触发 ''' def __init__(self, name): """类名加括号 给对象添加独有数据时自动触发""" self.name = name print('__init__') ''' 2.___str__ 对象被执行打印操作的时候自动触发 ''' def __str__(self): """ 对象在被执行打印操作的时候自动触发 该方法返回什么打印的结果就是什么 并且该方法必须要返回一个字符串类型的数据 """ return f'对象:{self.name}' ''' 3.__call__ 对象加括号调用的时候自动触发 ''' def __call__(self, *args, **kwargs): """ 对象加括号调用的时候自动触发 该方法返回什么对象调用之后的返回值就是什么 """ print('__call__') # print(*args, **kwargs) return 'return value' ''' 4.__getattr__ 对象点不存在的名字的时候自动触发 ''' def __getattr__(self, item): """对象在查找无法使用的名字时自动触发 该方法返回什么 点不存在的名字就可以得到什么""" print('__getattr__') # __getattr__ print(item) # age return 'jason' # jason ''' 5.__getattribute__ 对象点名字就会自动触发 有它的存在就不会执行上面的__getattr__ ''' def __getattribute__(self, item): """对象在查找名字的时候就会自动触发该方法 """ print('__getattribute__') return 'getattribute' print(type(item)) if hasattr(self, item): return getattr(self, item) return f'抱歉 {item}名字不存在' ''' 6.__setattr__ 给对象添加或者修改数据的时候自动触发 对象.名字 = 值 ''' def __setattr__(self, key, value): """当对象执行 对象.名字=值 的时候就会自动触发""" # print('__setattr__') # print(key, value) pass ''' 7.__enter__ 当对象被当做with上下文管理操作的开始自动触发 并且该方法返回什么 as后面的变量名就会接收到什么 ''' def __enter__(self): """当对象被当做with上下文管理操作的开始自动触发 并且该方法返回什么 as后面的变量名就会接收到什么""" return 'jason' ''' 8.__exit__ with上下文管理语法运行完毕之后自动触发(子代码结束) ''' def __exit__(self, exc_type, exc_val, exc_tb): """当对象参与的with上下文管理语法运行完毕之后自动触发(子代码结束)""" # f.close() pass # obj = Student('HaiMan') # print('__init__') 输出__init__ # print(obj) # 对象:HaiMan # print(obj.name) # HaiMan # obj() # print('__call__') 输出__call__ # obj(1, 2, {'name': 'jason'}) # 有print(*args, **kwargs) 输出1 2 {'name': 'jason'} # obj(1, 2, {'name': 'jason'}) # 无print(*args, **kwargs)时 print('__call__') 输出__call__ # print(obj.age) # 对象.不存在的名字触发 obj = Student('jason') with obj as f: print(f) # jason # with open() as f: # pass

1|2魔法方法笔试

''' 1.补全下列代码使得运行不报错即可 ''' class Context: pass with Context() as f: f.do_something() class Context: def do_something(self): pass def __enter__(self): return self def __exit__(self, exc_type, exc_val, exc_tb): pass with Context() as f: f.do_something() ''' 2. 自定义字典类型并让字典能够通过句点符的方式操作键值对 ''' class MyDict(dict): def __setattr__(self, key, value): self[key] = value def __getattr__(self, item): return self.get(item) obj = MyDict() obj.name = 'jason' obj.pwd = 18 obj.hobby = 'read' # print(obj) print(obj.name) print(obj.pwd) print(obj.hobby) # print(obj) # print(obj) # 字典存储的数据 {} # print(obj.__dict__) # 字典对象名称空间 {'name': 'jason'} print(type(obj))

1|3元类简介

"""推导步骤1:如何查看数据的数据类型""" # s1 = 'hello world' # str() # l1 = [11, 22, 33, 44] # list() # d1 = {'name': 'jason', 'pwd': 123} # dict() # t1 = (11, 22, 33, 44) # tuple() # print(type(s1)) # <class 'str'> # print(type(l1)) # <class 'list'> # print(type(d1)) # <class 'dict'> # print(type(t1)) # <class 'tuple'> """推导步骤2:其实type方法是用来查看产生对象的类名""" # class Student: # pass # obj = Student() # print(type(obj)) # <class '__main__.Student'> """推导步骤3:python中一切皆对象 我们好奇type查看类名显示的是什么""" class Student: pass obj = Student() print(type(obj)) # <class '__main__.Student'> print(type(Student)) # <class 'type'> class A:pass class B:pass print(type(A), type(B)) """结论:我们定义的类其实都是由type类产生的>>>:元类(产生类的类)"""

1|4创建类的两种方式

# 方式1:使用关键字class class Teacher: school_name = '老女儿' def func1(self):pass print(Teacher) print(Teacher.__dict__) # 方式2:利用元类type type(类名,类的父类,类的名称空间) cls = type('Student', (object,), {'name':'jason'}) print(cls) print(cls.__dict__) """ 了解知识:名称空间的产生 1.手动写键值对 针对绑定方法不好定义 2.内置方法exec 能够运行字符串类型的代码并产生名称空间 """

1|5元类定制类的产生行为

# coding:utf-8 """ 推导: 对象是由类名加括号产生的 __init__ 类是由元类加括号产生的 __init__ """ """所有的类必须首字母大写 否则无法产生""" # 1.自定义元类:继承type的类也称之为元类 class MyMetaClass(type): def __init__(cls, what, bases=None, dict=None): print('what', what) print('bases', bases) print('dict', dict) # istitle() 除了首字母,其他都是小写 if not what.istitle(): raise TypeError('类名首字母应该大写') super().__init__(what, bases, dict) # 2.指定类的元类:利用关键字metaclass指定类的元类 class Myclass(metaclass=MyMetaClass): desc = 'It\'s funny!' print(Myclass) print(Myclass.__dict__)

1|6元类定制对象的产生行为

# coding:utf-8 """ 推导: 对象加括号会执行产生该对象类里面的 __call__ 类加括号会执行产生该类的类里面的 __call__ """ # 给对象添加独有数据的时候 必须采用关键字参数传参 class MyClass(type): def __call__(self, *args, **kwargs): if args: raise '请按关键字传参!' return super().__call__(*args, **kwargs) class Student(metaclass=MyClass): def __init__(self, name, age, sexy): print('__init__') self.name = name self.age = age self.sexy = sexy # obj = Student('jason', 18, 'male') obj = Student(name='jason', age=18, sexy= 'male') print(obj.__dict__)

1|7魔法方法之双下new

# coding:utf-8 """ __new__可以产生空对象 """ class MyMeteClass(type): def __call__(self, *args, **kwargs): # 产生一个空对象 obj = self.__new__(self) # 调用__init__给对象添加独有的数据 self.__init__(obj, *args, **kwargs) # 返回创建好的对象 return obj class Student(metaclass=MyMeteClass): def __init__(self, name): self.name = name obj = Student('HaiMan') print(obj.name)

1|8双下new实现单例模式

# 单例模式 __new__实现 class Singleton(): _instance = None _flag = False def __init__(self): if not Singleton._flag: print('__init__执行了') Singleton._flag = True def __new__(cls, *args, **kwargs): # print('__new__执行了') if not Singleton._instance: print('__new__执行了') cls._instance = super().__new__(cls) return cls._instance obj = Singleton() print(obj) obj1 = Singleton() print(obj1)

__EOF__

本文作者少年奇妙游
本文链接https://www.cnblogs.com/HaiMan/p/16871040.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   负剑远游行归来仍少年  阅读(43)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Ollama——大语言模型本地部署的极速利器
· 使用C#创建一个MCP客户端
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示