反射实操与面向对象双下方法
反射实操
利用面向对象的反射编写系统终端
反射提供了一种不考虑代码,对数据和功能进行操作的方式
class WinCmd(object): # 定义一个WinCmd的类
def ls(self):
print('windows ls命令')
def dir(self):
print('windows dir命令')
def cd(self):
print('windows cd命令')
class Linux(object): # # 定义一个Linux的类
def ls(self):
print('linux ls命令')
def dir(self):
print('linux dir命令')
def cd(self):
print('linux cd命令')
obj1 = WinCmd() # 生成对象
print(obj1) # <__main__.WinCmd object at 0x0000017B0E7A23C8>
obj2 = Linux() # 生成对象
print(obj2) # <__main__.Linux object at 0x0000017B0E7A2470>
def run(obj):
while True:
cmd = input('cmd order>>>: ').strip() # 获取用户命令
if hasattr(obj, cmd): # 如果对象的名称空间有该字符串所对应的数据或者功能,结果为True
func_name = getattr(obj, cmd) # 如果对象的名称空间有该字符串所对应的数据或者功能,取其对应的数据或者功能
func_name()
else:
print('cmd order is not be found')
run(obj1) # 类似于win的cmd命令
run(obj2) # 类似linux的命令窗口
面向对象部分双下方法(内置方法)
面向对象中有一些方法名字是类似于__……__
的结构。这类方法也被人称为魔法方法。因为有些双下方法是不需要调用的,而是在特殊条件下自动触发的。比如__init__
方法会在对象实例化的时候自动触发。
class MyClass(object):
person: True
def __init__(self, name, age, gender): # 对象实例化
self.name = name
self.age = age
self.gender = gender
def __str__(self): # 对象展示的时候自动触发
print('打印操作')
return 'print'
def __del__(self): # 主动或者被动(执行结束,垃圾处理机制作用)删除对象的时候触发
print('删除操作')
pass
def __getattr__(self, item): # 获取数据或者功能,找不到时触发
print('爱而不得')
pass
def __call__(self, *args, **kwargs): # 对象被加括号调用的时候触发
print('调用对象')
pass
def __enter__(self): # with方法操作对象时触发
print('文件管理操作')
pass
def __exit__(self, exc_type, exc_val, exc_tb): # 结束操作对象时触发
print('文件管理操作结束')
pass
def __getattribute__(self, item): # 查找数据或功能时触发,无论能不能找到
print('大胆爱')
pass
'''在__getattr__方法和__getattribute__方法同时存在时,后者会顶替前者执行作用,前者不执行'''
obj1 = MyClass('oliver', 25, 'male')
print(obj1)
'''释放__getattr__方法,注掉__getattribute__方法'''
obj1.name # 能获取到
obj1.salary # 获取不到 爱而不得 (__gertattr__)
'''释放__getattribute__方法,注掉__getattr__方法'''
obj1.name # 大胆爱
obj1.salary # 大胆爱
'''释放__getattribute__方法,__getattr__方法'''
obj1.name # 大胆爱
obj1.salary # 大胆爱
'''在__getattr__方法和__getattribute__方法同时存在时,后者会顶替前者执行作用,前者不执行'''
obj1() # 调用对象
with obj1 as f:
print('进行文件操作') # 文件管理操作(__enter__) 进行文件操作 文件管理操作结束(__exit__)
更多方法:面向对象更多双下方法
问题处理
问题一: 使字典具备句点符取值的功能
class MyDict(dict):
def __getattr__(self, item): # 取对象中的名字是'item'的数据或者方法
return self.get(item) # 获得该名字所对应的数据或者功能名
def __setattr__(self, key, value): # 在名称空间中添加数据
self[key] = value # 以键值对的方式添加
obj1 = MyDict('oliver', 25)
print(obj1) # {'name': 'oliver', 'age': 25}
print(obj1.name) # oliver
print(obj1.age) # 25
obj1.gender = 'male' # 通过点的方式对对象的名称空间进行操作,添加数据
print(obj1) # {'name': 'oliver', 'age': 25, 'gender': 'male'}
print(obj1.salary) # None
问题二:代码补全问题
'''
题目:
class Context:
pass
with Context() as ctx:
ctx.do_something()
'''
'''
解决步骤:
分析:
类 Context -----> Context():产生对象 -----> with 操作 Context():需要有 __enter__ 和__exit__
-----> ctx.do_something() 对象用点的方式访问do_something,且do_something加了括号,所以对象有
do_something方法
'''
class Context:
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
return 123
def do_something(self):
print('代码已补全')
with Context() as ctx:
ctx.do_something() # 代码已补全