面向對象-反射-其他內置方法
阿新 • • 發佈:2019-05-13
school people tee foo 自動 sin 就是 系統資源 Coding 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
2.3repr和str
"沒有設置這兩個方法時"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
class School:
def __init__(self,name,addr,type):
self.name=name
self.addr=addr
self.type=type
s1=School(‘oldboy1‘,‘北京‘,‘私立‘)
print(‘from repr: ‘,repr(s1))
print(‘from str: ‘,str(s1))
print(s1)
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
from repr: <__main__.School object at 0x000001CC930BEAC8>
from str: <__main__.School object at 0x000001CC930BEAC8>
<__main__.School object at 0x000001CC930BEAC8>
Process finished with exit code 0
"可以顯式調用repr和str方法,
repr和str方法同時存在時,會優先調用str方法,
str方法沒有時,會調用repr方法
repr和str方法都是在print(obj)時調用的,沒有這兩個方法,輸出的是對象的內存地址,有了這兩個方法,就可以自行設置有意義的輸出"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
class School:
def __init__(self,name,addr,type):
self.name=name
self.addr=addr
self.type=type
def __repr__(self):
return ‘School(%s,%s)‘ %(self.name,self.addr)
def __str__(self):
return ‘(%s,%s)‘ %(self.name,self.addr)
s1=School(‘oldboy1‘,‘北京‘,‘私立‘)
# 可以顯式調用repr和str方法
print(‘from repr: ‘,repr(s1))
print(‘from str: ‘,str(s1))
print(‘from repr: ‘,s1.__repr__())
print(‘from str: ‘,s1.__str__())
print(s1)
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
from repr: School(oldboy1,北京)
from str: (oldboy1,北京)
from repr: School(oldboy1,北京)
from str: (oldboy1,北京)
(oldboy1,北京)
Process finished with exit code 0
2.4del
"程序正常結束後,或回收系統資源時如f.close(),會調用__del__"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
class Open:
def __init__(self,filename):
print(‘open file.......‘)
self.filename=filename
def __del__(self):
print(‘回收操作系統資源:self.close()‘)
f=Open(‘settings.py‘)
print(‘----main------‘)
"手動del,會提前執行__del__"
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
class Open:
def __init__(self,filename):
print(‘open file.......‘)
self.filename=filename
def __del__(self):
print(‘回收操作系統資源:self.close()‘)
f=Open(‘settings.py‘)
#程序結束的時候,會自動del f 回收f,就會執行__del__
del f # 如果沒有這行代碼,會先執行print(--main--),之後回收f,運行__del__,如果手動在這裏del,就會先執行__del__,然後執行後面語句
print(‘----main------‘)
E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
open file.......
回收操作系統資源:self.close()
----main------
Process finished with exit code 0
面向對象-反射-其他內置方法