一、引言

  有时候我们会碰到类似这样的需求,就是想要执行类的某个方法,或者需要对对象的某个参数赋值,而方法名或参数名已经包装在类中并不能去顶,需要通过参数传递字符串的形式输入。在这样的情况你会选择什么样的办法来解决吗?例如:

#!/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)\Python27\python.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)\Python27\python.exe" F:/Python/Alex/s12/Blog/reflect.py
Please write you want the animals:cat
喵喵喵 "D:\Program Files (x86)\Python27\python.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)\Python27\python.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)\Python27\python.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'

Python之反射的更多相关文章

  1. python的反射机制

    转载自:http://www.cnblogs.com/feixuelove1009/p/5576206.html 对编程语言比较熟悉的朋友,应该知道"反射"这个机制.Python作 ...

  2. python的反射

    目前大多数网站都是通过路由的方法来,处理url请求,如果有很多个url的话,不停的include或者用if判断匹配,似乎不太符合情理,因此这里讲讲python的反射机制, 自动装在模块.请看下面的实例 ...

  3. 简单谈谈python的反射机制

    转:http://www.jb51.net/article/87479.htm 本文主要介绍python中的反射,以及该机制的简单应用,熟悉JAVA的程序员,一定经常和Class.forName打交道 ...

  4. 【转】简单谈谈python的反射机制

    [转]简单谈谈python的反射机制 对编程语言比较熟悉的朋友,应该知道“反射”这个机制.Python作为一门动态语言,当然不会缺少这一重要功能.然而,在网络上却很少见到有详细或者深刻的剖析论文.下面 ...

  5. Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究

    Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: ​ 反射的概念是由Smith在1982年首次提出的 ...

  6. Python之反射,正则

    本节主要内容: 一. 反射: getattr hasattr setattr defattr 二. 补充模块中特殊的变量 三. 正则表达式 re模块 (一)反射: hasattr(object, na ...

  7. 关于PYTHON的反射,装饰的练习

    从基本概念,简单例子才能慢慢走到高级一点的地方. 另外,PYTHON的函数式编程也是我很感兴趣的一点. 总体而言,我觉得OOP可以作大的框架和思路,FP能作细节实现时的优雅牛X. ~~~~~~~~~~ ...

  8. 详解python之反射机制

    一.前言 def f1(): print('f1') def f2(): print('f2') def f3(): print('f3') def f4(): print('f4') a = 1 t ...

  9. 第六章:Python基础の反射与常用模块解密

    本课主题 反射 Mapping 介绍和操作实战 模块介绍和操作实战 random 模块 time 和 datetime 模块 logging 模块 sys 模块 os 模块 hashlib 模块 re ...

  10. python 异常 反射

    异常 反射 一.异常处理: AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x IOError 输入/输出异常:基本上是无法打开文件 ImportError ...

随机推荐

  1. [LintCode] Simplify Path 简化路径

    Given an absolute path for a file (Unix-style), simplify it. Have you met this question in a real in ...

  2. [CareerCup] 17.13 BiNode 双向节点

    17.13 Consider a simple node-like data structure called BiNode, which has pointers to two other node ...

  3. - dequeueReusableCellWithIdentifier:

    与之对应的还有一个方法: - dequeueReusableCellWithIdentifier:forIndexPath: 1 > - dequeueReusableCellWithIdent ...

  4. Displaying a full list of groups in Odoo's Kanban view

    Kanban view is probably the most flexible view in Odoo. It can be used for many different purposes. ...

  5. WordPattern

    Given a pattern and a string str, find if str follows the same pattern. Examples: pattern = "ab ...

  6. FK JavaScript:ArcGIS JavaScript类库加载不成功而导致的程序异常

    现象:页面加载时,有时候成功,有时候出错,出错的地方为init.js 加载esri的类库 经过仔细对比,发现出错时dojo加载的类库中,对象的很多属性都为undefined,而加载成功时,该对象的相关 ...

  7. sprin加载顺序

    spring加载有个比较有意思的问题,这里片很不错的文章 http://guoliangqi.iteye.com/blog/632697

  8. MacPort 的使用

    MacPorts 的安装和使用   官网下载最版本的 安装包   自动安装  可能会出现很慢的情况   设置环境变量   vim ~/.bash_profile      i  插入修改  :wq 保 ...

  9. js 字符串拼接

    正常来说已经使用es6 的 模板了如`` //页面层 layer.open({ type: 1, content:`<div class="child_card"> & ...

  10. springmvc Failed to load resource: the server responded with a status of 404 (Not Found)

    jsp页面导入css.js提示上述问题. Spring对静态资源的请求做专门处理 <!-- 对静态资源的请求 --><mvc:resources location="/js ...