一、反射
在Python中,反射指的是通过字符串来操作对象的属性,涉及到四个内置函数的使用
hasattr( ):判断对象是否含有字符串对应的功能或数据
getattr( ):根据字符串获取对应的变量名或者函数名
setattr( ):根据字符串给对象设置键值对( 名称空间的名字 )
delattr( ):根据字符串删除对象对应的键值对( 名称空间的名字 )
Python中一切皆对象,类和对象都可以用下述四个方法
在python中实现反射非常简单,在程序运行过程中,如果我们获取一个不知道存有何种属性的对象,若想操作其内部属性,可以先通过内置函数dir来获取任意一个类或者对象的属性列表,列表中全为字符串格式
class People:
def __init__(self,name,age,gender):
self.name=name
self.age=age
self.gender=gender
obj=People('egon',18,'male')
dir(obj) # 列表中查看到的属性全为字符串
[......,'age', 'gender', 'name']
接下来就是想办法通过字符串来操作对象的属性了,这就涉及到内置函数hasattr、getattr、setattr、delattr的使用了(Python中一切皆对象,类和对象都可以用下述四个方法)
class Teacher:
def __init__(self,full_name):
self.full_name =full_name
t=Teacher('jason Lin')
# hasattr(object,'name')
hasattr(t,'full_name') # 按字符串'full_name'判断有无属性t.full_name
# getattr(object, 'name', default=None)
getattr(t,'full_name',None) # 等同于t.full_name,不存在该属性则返回默认值None
# setattr(x, 'y', v)
setattr(t,'age',18) # 等同于t.age=18
# delattr(x, 'y')
delattr(t,'age') # 等同于del t.age
反射实例
class Wincmd:
def ls(self):
print('windows running -----ls')
def dir(self):
print('windows running -----dif')
class Linuxcmd:
def ls(self):
print('Linux running -----ls')
def dir(self):
print('Linux running -----dif')
def run(obj):
while True:
cmd = input('your command:').strip()
if hasattr(obj,cmd):
func_name = getattr(obj,cmd)
func_name()
break
else:
print('cmd command not found')
break
win = Wincmd()
lin = Linuxcmd()
if __name__ == '__main__':
run(win)
二、魔法方法
魔法方法其实就是在某种条件下回自动触发执行的方法,一般的结构就是 _ _ xxxx _ _, 有双下划线的方法
Python的Class机制内置了很多特殊的方法来帮助使用者高度定制自己的类,这些内置方法都是以双下划线开头和结尾的,会在满足某种条件时自动触发,我们以常用的__str__和__del__为例来简单介绍它们的使用
__str__方法会在对象被打印时自动触发,print功能打印的就是它的返回值,我们通常基于方法来定制对象的打印信息,该方法必须返回字符串类型
class People:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return '<Name:%s Age:%s>' %(self.name,self.age) #返回类型必须是字符串
p=People('lili',18)
print(p) # 触发p.__str__(),拿到返回值后进行打印
# <Name:lili Age:18>
__del__会在对象被删除时自动触发。由于Python自带的垃圾回收机制会自动清理Python程序的资源,所以当一个对象只占用应用程序级资源时,完全没必要为对象定制__del__方法,但在产生一个对象的同时涉及到申请系统资源(比如系统打开的文件、网络连接等)的情况下,关于系统资源的回收,Python的垃圾回收机制便派不上用场了,需要我们为对象定制该方法,用来在对象被删除时自动触发回收系统资源的操作
class People:
def __init__(self,name,age):
self.name=name
self.age=age
def __del__(self):
print("=======>")
obj = People('fuank',19)
del obj # 在对象obj被删除时,自动触发obj.__del__()
print('end')
"""
=======>
end
"""
class People:
def __init__(self,name,age):
self.name=name
self.age=age
def __del__(self):
print("=======>")
obj = People('fuank',19)
print('end')
# 垃圾回收机制会自动删除 obj,触发 del obj
"""
end
=======>
"""
常用的魔法方法补充
__getattr__
: 对象查找不存在名字的时候自动触发
__setattr__
: 对象在执行添加属性操作的时候自动触发 >>> obj.变量名=变量值
__call__
: 对象被加括号调用的时候自动触发 参考元类的介绍---->元类
__enter__
:
对象被执行with上下文管理语法开始自动触发
该方法返回什么as
后面的变量名
就会得到什么
__exit__
: 对象被执行with上下文管理语法结束之后自动触发
__getattribute__
: 只要对象查找名字无论名字是否存在都会执行该方法
如果类中有__getattribute__
方法 那么就不会去执行__getattr__
方法