面向對象--反射
阿新 • • 發佈:2017-08-17
turn print rep 引號 反射 field elf log 類和對象
什麽是反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以訪問、檢測和修改它本身狀態或行為的一種能力(自省)。這一概念的提出很快引發了計算機科學領域關於應用反射性的研究。它首先被程序語言的設計領域所采用,並在Lisp和面向對象方面取得了成績。
python面向對象中的反射:通過字符串的形式操作對象相關的屬性。python中的一切事物都是對象(都可以使用反射)
下列方法適用於類和對象(一切皆對象,類本身也是一個對象)
1)hasattr:可以查看前面的元素是否擁有後面的元素,後面的元素要用引號包裹,前面不需要。
但是這裏必須要實例化,如果是hasattr(Foo,‘name’)報False.
class Foo: def __init__(self,name,age): self.name=name self.age=age def func(self): print(‘yes‘) l1=Foo(‘egon‘,19) print(hasattr(l1,‘age‘)) l2=getattr(l1,‘age‘) print(l2) print(int(getattr(l1,‘age‘))-20) print(hasattr(l1,‘Foo‘))
2)getattr: 根據括號的元素拿到相應的值,getattr(l1,l2),也就是如果後面的元素屬於前面,那麽會取出l1.l2的值。如果不是那就報錯。
class Foo(object): staticField = "old boy" def __init__(self): self.name = ‘wupeiqi‘ def func(self): return ‘func‘ @staticmethod def bar(): return ‘bar‘ print(getattr(Foo, ‘staticField‘)) print(getattr(Foo, ‘func‘)) print(getattr(Foo, ‘bar‘))
實例化能得到結果,不實例化就指揮顯示內存地址。
class Foo(object): staticField = "old boy" def __init__(self): self.name = ‘wupeiqi‘ @staticmethod def func(): return ‘func‘ @classmethod def bar(cls): return ‘bar‘ print(getattr(Foo, ‘staticField‘)) l1=getattr(Foo, ‘func‘) l2=getattr(Foo, ‘bar‘) print(l1()) print(l2())
這裏有staticmethod使得getattr()裏面Foo得以實現
這裏還有一個sys模塊調用的方法。
import sys def s1(): print ‘s1‘ def s2(): print ‘s2‘ this_module = sys.modules[__name__] hasattr(this_module, ‘s1‘) getattr(this_module, ‘s2‘)
3)
__str__和__repr__
改變對象的字符串顯示__str__,__repr__
自定制格式化字符串__format__
class Foo: def __init__(self,name): self.name = name def __str__(self): return ‘%s obj info in str‘%self.name def __repr__(self): return ‘obj info in repr‘ f = Foo(‘egon‘) print(f) print(‘%s‘%f) print(‘%r‘%f) print(repr(f)) # f.__repr__() print(str(f))
這裏不管是__str__還是__repr__都是要return 的值,沒有則會報錯。
#當打印一個對象的時候,如果實現了str,打印中的返回值
#當str沒有被實現的時候,就會調用repr方法
#但是當你用字符串格式化的時候 %s和%r會分別去調用__str__和__repr__
#不管是在字符串格式化的時候還是在打印對象的時候,repr方法都可以作為str方法的替補
#但反之不行
#用於友好的表示對象。如果str和repr方法你只能實現一個:先實現repr
面向對象--反射