1. 程式人生 > >面向對象--反射

面向對象--反射

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

面向對象--反射