Python反射實例解析

在Python中,反射的作用是很重要的,而它的作用就是通過字符串映射或修改程序運行時的狀態、屬性、方法。

具體的有以下四種

1、getattr

    getattr(object, name, default=None)    # 獲取一個對象裏對應字符串的方法
def getattr(object, name, default=None): # known special case of getattr
    """
    getattr(object, name[, default]) -> value

    Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
    When a default argument is given, it is returned when the attribute doesn't
    exist; without it, an exception is raised in that case.
    """
    pass

2、hasattr

hasattr(obj,name_str)  # 判斷obj中有沒有一個對應name_str字符串對應的方法或屬性
def hasattr(*args, **kwargs): # real signature unknown
    """
    Return whether the object has an attribute with the given name.
    
    This is done by calling getattr(obj, name) and catching AttributeError.
    """
    pass

3、setattr

setattr(x, y, v)    # 設置屬性或方法
def setattr(x, y, v): # real signature unknown; restored from __doc__
    """
    Sets the named attribute on the given object to the specified value.
    
    setattr(x, 'y', v) is equivalent to ``x.y = v''
    """
    pass

4、delattr

delattr(x, y)    # 刪除屬性或方法
def delattr(x, y): # real signature unknown; restored from __doc__
    """
    Deletes the named attribute from the given object.
    
    delattr(x, 'y') is equivalent to ``del x.y''
    """
    pass

 

分別以hasattr、getattr、setattr、delattr舉例:

首先,hasattr:

class Foo(object):
    def __init__(self,name):
        self.name = name


    def test(self):
        print("%s is testing..."%self.name)

d = Foo("Tom")
choice = input(">>>>:").strip()
# d.choice  行不通,choice是字符串

print(hasattr(d,choice))    # 判斷eat方法是否存在

然後,getattr:

class Foo(object):
    def __init__(self,name):
        self.name = name

    def test(self):
        print("%s is test......"%self.name)

d = Foo("Tom")
choice = input(">>>>:").strip()
print(getattr(d,choice))    # 打印eat方法在內存中的對象地址
c = getattr(d,choice)
c()

緊接着,setattr:

# 第一種,設置方法
def bulk(self):
    print("%s is d...."%self.name)    # 新加方法

class Foo(object):
    def __init__(self,name):
        self.name = name


    def test(self):
        print("%s is test......"%self.name)

d = Foo("Tom")
choice = input(">>>>:").strip()
if hasattr(d,choice):
    f = getattr(d,choice)
    f()
else:
    setattr(d,choice,bulk)      # 動態向class裏面裝入了一個方法
    d.bulk(d)           
# 這裏的b.bluk僅僅是個變量名,隨時可以替代,
# 如寫成d.talk(d),那麼也是沒有問題的,不過後面調用的時候choice的input就要變成talk方法
# 第二種,設置(修改)屬性
def bulk(self):
    print("%s is d...."%self.name)    # 新加方法

class Foo(object):
    def __init__(self,name):
        self.name = name


    def test(self):
        print("%s is testing..."%self.name)

d = Foo("Tom")
choice = input(">>>>:").strip()
if hasattr(d,choice):
    setattr(d,choice,'Dom')     # 將已有的str進行修改了,待打印name的時候,name就變了   
# 動態傳入屬性
else:
    setattr(d,choice,None)      # 動態傳入屬性
    print(getattr(d,choice))
print(d.name) 

最後,delattr:

class Foo(object):
    def __init__(self,name):
        self.name = name


    def test(self):
        print("%s is test......"%self.name)

d = Foo("Tom")
choice = input(">>>>:").strip()

if hasattr(d,choice):
    delattr(d,choice)

print(d.name)

 

總結:

# 反射:
# hasattr(obj,name_str),判斷一個對象obj裏是否有對應的name_str字符串的方法
# getattr(obj,name_str),根據字符串去獲取obj對象裏的對應的方法的內存地址
# setattr(obj,'y',z),通過字符串設定屬性,is equivalent to ``x.y = v'',給對象添加新屬性
# delattr(obj,name_str),刪除

實際上就是把字符串反射回內存中的地址,來回映射,實現動態內存裝配。

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章