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),删除

实际上就是把字符串反射回内存中的地址,来回映射,实现动态内存装配。

扫描二维码关注公众号,回复: 9128495 查看本文章
发布了36 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Jack0610/article/details/102935613