一、引言
有时候我们会碰到类似这样的需求,就是想要执行类的某个方法,或者需要对对象的某个参数赋值,而方法名或参数名已经包装在类中并不能去顶,需要通过参数传递字符串的形式输入。在这样的情况你会选择什么样的办法来解决吗?例如:
#!/usr/bin/env python # -*- coding=utf-8 -*- class Action(object): def dog(self): print("汪汪汪") def cat(self): print("喵喵喵") if __name__ == "__main__": animal = raw_input("Please write you want the animals:") act = Action() if animal == "dog": act.dog() elif animal == "cat": act.cat() 执行结果如下: "D:Program Files (x86)Python27python.exe" F:/Python/Alex/s12/Blog/reflect.py Please write you want the animals:cat 喵喵喵
在上面的代码中使用if语句的话,就是你每写一个方法就得有一个elif语句来判断,假如有1000个方法,这样就得有1000个elif语句。这么看是不是弱爆了。那么我们就来改写上面的代码:
#!/usr/bin/env python # -*- coding=utf-8 -*- class Action(object): def dog(self): print("汪汪汪") def cat(self): print("喵喵喵") if __name__ == "__main__": animal = raw_input("Please write you want the animals:") act = Action() if hasattr(act,animal): func = getattr(act,animal) func() else: print("You write the animal is not existed !") 执行结果如下: "D:Program Files (x86)Python27python.exe" F:/Python/Alex/s12/Blog/reflect.py Please write you want the animals:cat 喵喵喵 "D:Program Files (x86)Python27python.exe" F:/Python/Alex/s12/Blog/reflect.py Please write you want the animals:snake You write the animal is not existed !
在这里使用到了hasattr()和getattr()两个python的内建函数。通俗的对这两个内建函数讲解一下:
hasattr(act,animal) ----> 该语句的意思是:将输入的字符串与实例中的方法进行匹配,如果匹配上就返回True,匹配不上就返回False。
getattr(act,animal) ----> 该语句的意思是:将输入的字符串与实例中的方法进行匹配,如果匹配上就返回方法的内存地址,匹配不上就会有报错,见下图:
#!/usr/bin/env python # -*- coding=utf-8 -*- class Action(object): def dog(self): print("汪汪汪") def cat(self): print("喵喵喵") if __name__ == "__main__": animal = raw_input("Please write you want the animals:") act = Action() # if hasattr(act,animal): func = getattr(act,animal) # func() # else: # print("You write the animal is not existed !") 执行结果如下: "D:Program Files (x86)Python27python.exe" F:/Python/Alex/s12/Blog/reflect.py Please write you want the animals:tiger Traceback (most recent call last): File "F:/Python/Alex/s12/Blog/reflect.py", line 14, in <module> func = getattr(act,animal) AttributeError: 'Action' object has no attribute 'tiger'
因此在使用getattr()是可以结合hasattr()或者在方法名确定情况下进行调用!
除了getatta()和hasattr()外,还有setattr()和delattr()。
下面通过例子来全面了解这四个内建函数:
>>> class myClass(object): ... def __init__(self): ... self.foo = 100 ... myInst = myClass() >>> hasattr(myInst,'foo') True >>> getattr(myInst,'foo') 100 >>> hasattr(myInst,'bar') False >>> getattr(myInst,'bar') Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'myClass' object has no attribute 'bar' >>> setattr(myInst,'bar','my attr') >>> dir(myInst) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar', 'foo'] >>> getattr(myInst,'bar') 'my attr' >>> delattr(myInst,'foo') >>> dir(myInst) ['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'bar'] >>> hasattr(myInst,'foo') False
二、总结:
hasattr()函数是布朗型的,它的目的就是为了决定一个对象是否有一个特定的属性,一般用于访问某属性前先做一下检查。getattr()和setattr()函数相应地取得和赋值给对象的属性,getattr()会在你试图读取一个不存在的属性时,引发AttributeError异常,除非给出那个可选的默认参数。setattr()将要么加入一个新的属性,要么取代一个已存在的属性。而delattr()函数会从一个对象中删除属性。
三、全面解析:
#!/usr/bin/env python # -*- coding=utf-8 -*- class Action(object): def __init__(self,country,zoo): self.country = country self.zoo = zoo def dog(self): print("汪汪汪") def cat(self): print("喵喵喵") def animal_place(ins,name): print("the animal's place is ",name,ins.country) if __name__ == "__main__": animal = raw_input("Please write you want the animals:") act = Action('USA','zoo') if hasattr(act,animal): func = getattr(act,animal) #获取act.dog内存地址 func() #act.dong() else: print("You write the animal is not existed !") #想要让函数animal_place能跟实例act中方法一样执行 setattr(act,'run',animal_place) act.run(act,'cat') #删除类Action中cat方法 act.cat() delattr(Action,'cat') act.cat() #删除实例act中country的属性 print(act.country) delattr(act,'country') print(act.country) 执行结果如下: "D:Program Files (x86)Python27python.exe" F:/Python/Alex/s12/Blog/reflect.py Please write you want the animals:dog 汪汪汪 ("the animal's place is ", 'cat', 'USA') 喵喵喵 Traceback (most recent call last): File "F:/Python/Alex/s12/Blog/reflect.py", line 31, in <module> act.cat() AttributeError: 'Action' object has no attribute 'cat' USA Traceback (most recent call last): File "F:/Python/Alex/s12/Blog/reflect.py", line 35, in <module> print(act.country) AttributeError: 'Action' object has no attribute 'country'