反射
反射
通过字符串来获取,设置,删除对象中的属性或方法
- 用户输入一串字符串,执行该字符串对应的方法
- hasattr() :判断一个属性是否在对象中,返回true或者False
- getattr() :通过字符串获取属性和方法,如果获取到了,就会返回相应的属性和方法
- setattr():通过字符串来设置属性和方法
- delatter():通过字符串来删除属性和方法
class Foo:
def fun(self):
print('run')
def speak(self):
print('speak')
p = Foo()
print(Foo.__dict__)#返回类的所有的方法{'__module__': '__main__', 'fun': <function Foo.fun at 0x0000014650AB7168>, 'speak': <function Foo.speak at 0x0000014650AB74C8>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
cmd = input('请输入命令')
# 方案一
# 执行类中的方法
print(Foo.__dict__[cmd])#方法的内存地址
Foo.__dict__[cmd](p)
# 方案二
# 执行类中的方法
if hasattr(p,cmd):#判断一个属性是否在对象中,返回true或者False
run = getattr(p,cmd)#run方法的内存地址# 通过字符串获取属性和方法,如果获取到了,就会返回相应的属性和方法
run()
else:
print('没有这个命令')
-
setattr():通过字符串来设置属性和方法
-
放属性
class Foo: def fun(self): print('run') def speak(self): print('speak') p = Foo() # 通过用户输入key和value往对象中赋值 key = input('请输入key:')#qq value = input('请输入value:')#123 setattr(p,key,value) print(p.__dict__) #{'qq': '123'}
-
放方法
class Foo: def fun(self): print('run') def speak(self): print('speak') p = Foo() # 动态的往对象里面放方法 def teat(a): print(a) print(p.__dict__)#{} setattr(p,'teat',teat) print(p.__dict__)#{'teat': <function teat at 0x000002968CC37168>} p.teat(11)#11
-
-
delatter():通过字符串来删除属性和方法
-
原始的删除
class Foo: def fun(self): print('run') def speak(self): print('speak') p = Foo() # 原始的删除 p.name = 'czq' print(p.__dict__)#{'name': 'czq'} del p.name print(p.__dict__)#{}
-
动态删除p中的属性为变量a的属性
class Foo: def fun(self): print('run') def speak(self): print('speak') p = Foo() p.name = 'czq' p.age = 18 p.sex = 'male' print(p.__dict__)#{'name': 'czq', 'age': 18, 'sex': 'male'} a = input('请输入需要删除的属性:')#name delattr(p,a) print(p.__dict__)#{'age': 18, 'sex': 'male'}
-
用法
class BlackMedium:
feature = 'Ugly'
def __init__(self,name,addr):
self.name = name
self.addr = addr
def sell_house(self):
print('%s 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼' % self.name)
def rent_house(self):
print('%s 黑中介租房子啦,傻逼才租呢' %self.name)
b1=BlackMedium('玉皇大帝','回龙观')
# print(b1.__dict__)#对象的属性,{'name': '玉皇大帝', 'addr': '回龙观'}
# print(BlackMedium.__dict__)#类的方法,{'__module__': '__main__', 'feature': 'Ugly', '__init__': <function BlackMedium.__init__ at 0x0000012D3A3F7438>, 'sell_house': <function BlackMedium.sell_house at 0x0000012D3A3F7558>, 'rent_house': <function BlackMedium.rent_house at 0x0000012D3A3F75E8>, '__dict__': <attribute '__dict__' of 'BlackMedium' objects>, '__weakref__': <attribute '__weakref__' of 'BlackMedium' objects>, '__doc__': None}
方法一
print(hasattr(b1,'sell_house'))#True,sell_house是对象的方法
a = 'sell_house'
getattr(b1,a)()#玉皇大帝 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼
方法二
sell_house = getattr(b1,a)
sell_house()#玉皇大帝 黑中介卖房子啦,傻逼才买呢,但是谁能证明自己不傻逼
name = getattr(b1,'name')
print(name)#玉皇大帝
删除属性和方法
print(b1.__dict__)#{'name': '玉皇大帝', 'addr': '回龙观'}
delattr(b1,'name')
print(b1.__dict__)#{'addr': '回龙观'}
使用自己写的模块,通过反射来获取模块中是否有我要使用的属性或方法,# 如果有就执行,没有,就报错
#utils.py
#别人写的,领导规定要写speak,run,eat方法
#这个人没写完
def speak():
print('speak')
def run():
print('run')
#这个人写完了
def eat():
print('eat')
import utils
utils.speak()
if hasattr(utils,'speak'):
speak=getattr(utils,'speak')
speak()
# 我以为它写完了
utils.eat()
# 更安全
if hasattr(utils,'eat'):
eat=getattr(utils,'eat')
eat()
else:
print('那个人还没写完呢')