一、引言

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

#!/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] Swap Two Nodes in Linked List 交换链表中的两个结点

    Given a linked list and two values v1 and v2. Swap the two nodes in the linked list with values v1 a ...

  2. js实现事件模型bind与trigger

    function Emitter() { this._listener = [];//_listener[自定义的事件名] = [所用执行的匿名函数1, 所用执行的匿名函数2] } //注册事件 Em ...

  3. Java获取前天和后天的时间

    import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Calendar;import j ...

  4. Linux下配置Lamp

    linux下配置lamp步骤: 一.快速安装Apache+PHP5+MySql 先更新: # yum update 然后安装LAMP环境:(163的yum源上只有php5.1.6 mysql 5.0. ...

  5. MySQL 5.7贴心参数之binlog_row_image

    相信大家都了解mysql binlog的格式,那就是有三种,分别是STATEMENT,MiXED,ROW.各有优劣,具体的请大家自行查阅资料.在MySQL 5.7版本以前,虽然ROW格式有各种各样的好 ...

  6. jetBrains phpstorm/webstorm 编辑器使用诀窍

    下载地址 https://www.jetbrains.com/products.html?fromMenu CTRL + F12 / COMMAND + F12 打开类中的结构 Ctrl + b / ...

  7. PHP如何通过SQL语句将数据写入MySQL数据库呢?

    1,php和MySQL建立连接关系 2,打开 3,接受页面数据,PHP录入到指定的表中 1.2两步可直接使用一个数据库链接文件即可:conn.php <?phpmysql_connect(&qu ...

  8. javascript:正则大全

    :replace函数,为写自己的js模板做准备 待完善 function 1,声明&用法 //数组: var arr=[];//字面量 var arr=new Array();//构造函数 / ...

  9. Run P4 without P4factory - A Simple Example In Tutorials. -2

    Reference:Github-Tutorial Exercise 2: Implementing TCP flowlet switching 实验准备: 参考之前的博客:Run P4 withou ...

  10. 远程出发jenkins jobs

    wget -O - -q "http://jenkins_server/job/ttt/buildWithParameters?TEST1=Value" wget -O - -q ...