一、引言

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

#!/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下安装配置Apache+PHP+MariaDB

    一.安装apache 1.下载并安装apache yum install httpd 2.启动apache systemctl start httpd.service 3.停止apache syste ...

  2. C#面向对象整理

    一.里氏转换 (1)子类可以赋值给父类:如果有一个地方需要一个父类作为参数,我们可以给一个子类代替. (2)如果父类装的是子类对象,那么这个父类可以强转为子类对象. 二.值类型跟引用类型区别 1.在内 ...

  3. winform把图片存储到数据库

    1.先在Form中放一个PictureBox控件,再放三个按钮. 2.双击打开按钮,在里面写如下代码: OpenFileDialog open1 = new OpenFileDialog(); Dia ...

  4. .net 设置导航的当前状态

    1.静态地址共用母版页时,加当前页的状态(使用加参数的方法实现): a: main.Master为链接设参数 MenuId <li> <a <%=MenuId==?" ...

  5. window.open()&&window.showmodaldialog()

    open 打开一个新窗口,并装载URL指定的文档,或装载一个空白文档,如果没提供URL的话. 适用于 窗口 语法 window = object.open([URL[,name[,features[, ...

  6. zendFream 中的用到了Ajax(其中有搜索)分页

    最近在用ZendFreamwork开发一个后台,其中用到了分页,ZendFreamwork自带的分页挺好用的,可是我其中用到了Ajax的局部刷新,在加上一些搜索条件,所以分页有点无头绪了.下面我来介绍 ...

  7. java开发常用工具类

    package com.rui.util; import java.text.DateFormat; import java.text.DecimalFormat; import java.text. ...

  8. jquery 温故而知新 Ul 相关的操作

    在UL中取得第一级的LI   <div id='demo1'> <ul> <li id='1'>1<li> <li id='2'>2< ...

  9. WxInput模块则比较彻底的解决了这个问题

    基于wxpython的GUI输入对话框2 在程序输入中,有时会要求同时改变多个参数值,而且类型也不尽相同, 这时TextEntryDialog就显得不适用了.WxInput模块则比较彻底的解决了这个问 ...

  10. 百度Site App的uaredirect.js实现手机访问,自动跳转网站手机版

    以下为代码,可放置在网站foot底部文件,或者haead顶部文件,建议将代码放在网站顶部,这样可以实现手机访问立即跳转! <script src="http://siteapp.bai ...