1.反射
1.1反射含义
通过字符串的形式操作对象的相关属性。
方法有hasattr,getattr,delattr
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
class People:
country='China'
def __init__(self,name,age):
self.name=name
self.age=age
def talk(self):
print('%s is talking' %self.name)
obj=People('egon',18)
print(obj.name) #obj.__dict__['name']
print(obj.talk)
choice='name'
# 这样直接使用字符串是不可以的,报错信息 AttributeError: 'People' object has no attribute 'choice'
# print(obj.choice) #print(obj.'name')
#但是反射,可以通过字符串操作对象中的属性
print("hasattr(obj,'name')===",hasattr(obj,'name')) #等同obj.name #obj.__dict__['name']
print("hasattr(obj,'talk')===",hasattr(obj,'talk')) #等同#obj.talk
print("hasattr(obj,'talk12')===",hasattr(obj,'talk12'))
print("getattr(obj,'namexxx',None)===",getattr(obj,'namexxx',None))
print("getattr(obj,'talk',None)===",getattr(obj,'talk',None))
setattr(obj,'sex','male') #obj.sex='male'
print("setattr(obj,'sex','male')===",obj.sex)
delattr(obj,'age') #del obj.age
print("delattr(obj,'age')===",obj.__dict__)
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
egon
<bound method People.talk of <__main__.People object at 0x000001B3F1348940>>
hasattr(obj,'name')=== True
hasattr(obj,'talk')=== True
hasattr(obj,'talk12')=== False
getattr(obj,'namexxx',None)=== None
getattr(obj,'talk',None)=== <bound method People.talk of <__main__.People object at 0x000001B3F1348940>>
setattr(obj,'sex','male')=== male
delattr(obj,'age')=== {'name': 'egon', 'sex': 'male'}
Process finished with exit code 0
1.2反射的应用
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
#反射的应用:
class Service:
def run(self):
while True:
inp=input('>>: ').strip() #cmd='get a.txt'
cmds=inp.split() #cmds=['get','a.txt']
# print(cmds)
if hasattr(self,cmds[0]):
func=getattr(self,cmds[0])
func(cmds)
def get(self,cmds):
print('get.......',cmds)
def put(self,cmds):
print('put.......',cmds)
obj=Service()
obj.run()
print("getattr(obj,'namexxx',None)===",getattr(obj,'namexxx',None))
print("getattr(obj,'talk',None)===",getattr(obj,'talk',None))
setattr(obj,'sex','male') #obj.sex='male'
print("setattr(obj,'sex','male')===",obj.sex)
delattr(obj,'age') #del obj.age
print("delattr(obj,'age')===",obj.__dict__)
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
>>: get a.txt
get....... ['get', 'a.txt']
2.其他内置方法
2.1item系列
__getitem__ obj['name']像字典一样调用属性的时候会触发__getitem__执行
__setitem__ obj['age']=22像字典一样设置属性的时候会触发__setitem__执行
__delitem__ del obj['age']像字典一样删除属性的时候会触发__delitem__执行
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
class Foo: #Dict
def __init__(self,name):
self.name=name
def __getitem__(self, item):
print('getitem...self.__dict__.get(%s)'%item)
# 这里不返回,obj['name']是不会获取到值的,因为这样操作就是执行__getitem__方法
return self.__dict__.get(item)
def __setitem__(self, key, value):
print("setitem...self.__dict__[%s]=%s"%(key,value))
self.__dict__[key]=value
def __delitem__(self, key):
print("delitem...del self.__dict__[%s]"%key)
del self.__dict__[key]
obj=Foo('egon')
# 查看属性
print(obj.__dict__)
# getitem触发时机:obj['name']像字典一样调用属性的时候,会触发
print("obj['name']",obj['name']) #结果egon
print("obj['namexx']",obj['namexx']) # 没有,返回None
print("obj.name",obj.name) # 这样不会触发__getitem__,必须让字典一样操作才会触发
#设置属性
obj.sex='male' #这样不会触发__setitem__,但也能给对象添加数据属性
print("obj.sex='male'====",obj.__dict__)
print("obj.sex======",obj.sex)
obj["age"]=22
print("obj['age']=22======",obj.__dict__)
print("obj.age======",obj.age) #设置后,可以直接使用对象来获取数据属性
#删除属性
del obj.sex #这样不会触发__del__item
print("del obj.sex====",obj.__dict__)
del obj['age']
print("del obj['age']====",obj.__dict__)
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
{'name': 'egon'}
getitem...self.__dict__.get(name)
obj['name'] egon
getitem...self.__dict__.get(namexx)
obj['namexx'] None
obj.name egon
obj.sex='male'==== {'name': 'egon', 'sex': 'male'}
obj.sex====== male
setitem...self.__dict__[age]=22
obj['age']=22====== {'name': 'egon', 'sex': 'male', 'age': 22}
obj.age====== 22
del obj.sex==== {'name': 'egon', 'age': 22}
delitem...del self.__dict__[age]
del obj['age']==== {'name': 'egon'}
Process finished with exit code 0
2.2isinstance和issubclass
"isinstance(obj,cls)检查是否obj是否是类 cls 的对象"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
class Foo(object):
pass
obj = Foo()
print(isinstance(obj, Foo))
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
True
Process finished with exit code 0
"issubclass(sub, super)检查sub类是否是 super 类的派生类"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
class Foo(object):
pass
class Bar(Foo):
pass
print(issubclass(Bar, Foo))
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
True
Process finished with exit code 0