一、引言

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

#!/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. linux笔记十----虚拟机网络配置

    首先,参考了博客http://blog.csdn.net/qianggezhishen/article/details/45841723,可以学会怎样确定界面类型

  2. Oracle三大经典表连接适用情况

    1.1环境准备 1.2 Nested Loops Join 从上面的试验来看,nested loop jion基本上是没有限制的,可以支持所有的运算. 1.3 Hash Join 1.4 Merge ...

  3. redis 安装(centos 6.4)

    我使用6.4系统,mark一下,其他版本应该也一样. wget wget http://download.redis.io/releases/redis-3.0.6.tar.gz make make ...

  4. 需要注意学习.net过程的要点

    基础部分 C# 基础语法 OOP的概念,面向对象的理解 继承 封装 多态 ASP.NET MVC (Web Form 用的越来越少,如果你不熟悉,可以不看) JavaScript 基础语法 如何在HT ...

  5. java环境搭建系列:JDK从下载安装到简单使用

    最近,问的比较多的问题居然是jdk的问题,对于新手来说这确实有点难度,毕竟一个人经常上网浏览新闻和观看视频的人,一下子开始一门编程语言的环境搭建.这中间需要一个慢慢适应的过程.回想当初我在这个阶段也很 ...

  6. mac El Capitan 10.11.6

    http://bbs.pcbeta.com/forum.php?mod=viewthread&tid=1702502&authorid=4532202&page=1

  7. ios-NSMutableAttributedString 更改文本字符串颜色、大小

    NSString * string = [NSString stringWithFormat:@"您的号码是%@号",[self backString:dic[@"ran ...

  8. Objective-C基础语法快速入门

    Objective-C基础语法快速入门 2010-11-04 16:32 折酷吧 zheku8 字号:T | T 假如我们对面向对象的思维已经C语言都很熟悉的话,对于我们学习Objective-C将会 ...

  9. xx.substring(x,x)和xx.index()

    [转的]用一个例子解释: ip = "126.168.1.1"; i = ip.indexOf('.');                           这里默认从0开始找到 ...

  10. JS之原型对象

    1.__proto__ 每个对象都有一个__proto__属性,指向该对象的原型对象 <script> var person = function(name,city){ this.nam ...