python -- 面向对象 -- 反射

python -- 面向对象 -- 反射

hasattr 判断对象内部是否有对应的字符串方法

hasattr(obj, name_str),判断obj中是否有叫name_str的方法

getattr 根据字符串的方法,使用这个方法

getattr(obj, name_str), 在obj中使用name_str的方法

setatter 根据字符串,给类创建一个叫字符串的方法

setattr(x, 'y', v) --> x.y = v
使用setattr需要在类的外面先定义好函数

综合使用

  • 给对象动态装配一个方法
def nothing(self):
    print("There are nothing here!!!")


class Human(object):

    def __init__(self, name):
        self.NAME = name

    def eat(self, food):
        print('{0} is eating {1}...'.format(self.NAME, food))


obj1= Human('Gao')

# 让用户输入一些Human的方法,可能是Human类中有的,也可能是没有的
choice = input('请选择Human的方法>>:').strip()

if hasattr(obj1, choice):
    func = getattr(obj1, choice)
    food_input = input("请投放食物>>:")
    func(food_input)

else :
    # 将外部的方法,通过setattr装配带实例化的对象中去。
    setattr(obj1, choice, nothing)  # setattr(实例化后的对象,输入的方法字符串,对应的方法)
    func = getattr(obj1,choice)  # 将choice对应的字符串,装配到obj1去,此时方法名就是choice对应的字符串,
                                 # 最后将obj1.choice赋值给func使用。
                                 # 譬如obj1.walk(),不过obj1.walk()对应就是Human类外面的noting的函数。
    func(obj1)  # 调用这个临时装配的func方法


'''
以下是程序的结果:
请选择Human的方法>>:walk
There are nothing here!!!
'''
  • 给对象动态装配一个属性
class Human(object):

    def __init__(self, name):
        self.NAME = name

    def eat(self, food):
        print('{0} is eating {1}...'.format(self.NAME, food))


obj1= Human('Gao')

# 让用户输入一些Human的方法,可能是Human类中有的,也可能是没有的
choice = input('请选择Human的新属性>>:').strip()

if hasattr(obj1, choice):
    func = getattr(obj1, choice)
    food_input = input("请投放食物>>:")
    func(food_input)

else :
    # 动态装一个类的属性,通过setattr装配到对象中去。
    setattr(obj1, choice, None)  # setattr(实例化后的对象,输入的方法字符串,对应的属性)
    func = getattr(obj1,choice)  # 将choice对应的字符串,装配到obj1去,此时对象属性就是choice对应的字符串,
                                 # 最后将obj1.choice的属性值就是None。也可以将属性值设置一个默认值,这里的默认值是None。
                                 # 譬如obj1.what,打印obj1.what时,就是None。
    print(func)  # 打印func这个对象属性


'''
以下是程序的结果:
请选择Human的新属性>>:what
None
'''
  • 如果是修改对象内的原有属性
class Human(object):

    def __init__(self, name):
        self.NAME = name

    def eat(self, food):
        print('{0} is eating {1}...'.format(self.NAME, food))


obj1= Human('Gao')

# 让用户输入一些Human的方法,可能是Human类中有的,也可能是没有的
choice = input('请选择Human的属性>>:').strip()

if hasattr(obj1, choice):  # 如果这里使用的对象中的原有属性时,打印attr的时候,会获得原有的属性值
    # attr = getattr(obj1, choice)  # 这句代码的意思是将输入的字符串找到对象中的属性值。
    attr1 = setattr(obj1, choice, None)  # 这里是将原有的对象的属性值,修改成None,最后再程序结尾,打印这个值时就显示None了。

else :
    # 动态装一个类的属性,通过setattr装配到对象中去。
    setattr(obj1, choice, None)  # setattr(实例化后的对象,输入的方法字符串,对应的属性)
    func = getattr(obj1,choice)  # 将choice对应的字符串,装配到obj1去,此时对象属性就是choice对应的字符串,
                                 # 最后将obj1.choice的属性值就是None。也可以将属性值设置一个默认值,这里的默认值是None。
    print(func)  # 打印func这个对象属性


print(obj1.NAME)

'''
以下是程序的结果:
请选择Human的属性>>:NAME
None
'''

delattr 动态删除对象中的属性

class Human(object):

    def __init__(self, name):
        self.NAME = name

    def eat(self, food):
        print('{0} is eating {1}...'.format(self.NAME, food))


obj1= Human('Gao')

# 让用户输入一些Human的方法,可能是Human类中有的,也可能是没有的
choice = input('请选择Human的属性>>:').strip()

if hasattr(obj1, choice):  # 如果这里使用的对象中的原有属性时,打印attr的时候,会获得原有的属性值
    # attr = getattr(obj1, choice)  # 这句代码的意思是将输入的字符串找到对象中的属性值。
    delattr(obj1, choice)  # 这里是将原有的对象的属性值删除,最后在程序结尾,打印这个值时就会报错。

else :
    # 动态装一个类的属性,通过setattr装配到对象中去。
    setattr(obj1, choice, None)  # setattr(实例化后的对象,输入的方法字符串,对应的属性)
    func = getattr(obj1,choice)  # 将choice对应的字符串,装配到obj1去,此时对象属性就是choice对应的字符串,
                                 # 最后将obj1.choice的属性值就是None。也可以将属性值设置一个默认值,这里的默认值是None。
    print(func)  # 打印func这个对象属性


print(obj1.NAME)

'''
以下是程序的结果:
请选择Human的属性>>:NAME
Traceback (most recent call last):
  File "E:/GitHub/py/lesson/lesson/a1.py", line 35, in <module>
    print(obj1.NAME)
AttributeError: 'Human' object has no attribute 'NAME'
'''
posted @ 2017-10-09 15:54  gzz041  阅读(239)  评论(0)    收藏  举报