Python之反射
一、引言
有时候我们会碰到类似这样的需求,就是想要执行类的某个方法,或者需要对对象的某个参数赋值,而方法名或参数名已经包装在类中并不能去顶,需要通过参数传递字符串的形式输入。在这样的情况你会选择什么样的办法来解决吗?例如:
#!/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之反射的更多相关文章
- python的反射机制
转载自:http://www.cnblogs.com/feixuelove1009/p/5576206.html 对编程语言比较熟悉的朋友,应该知道"反射"这个机制.Python作 ...
- python的反射
目前大多数网站都是通过路由的方法来,处理url请求,如果有很多个url的话,不停的include或者用if判断匹配,似乎不太符合情理,因此这里讲讲python的反射机制, 自动装在模块.请看下面的实例 ...
- 简单谈谈python的反射机制
转:http://www.jb51.net/article/87479.htm 本文主要介绍python中的反射,以及该机制的简单应用,熟悉JAVA的程序员,一定经常和Class.forName打交道 ...
- 【转】简单谈谈python的反射机制
[转]简单谈谈python的反射机制 对编程语言比较熟悉的朋友,应该知道“反射”这个机制.Python作为一门动态语言,当然不会缺少这一重要功能.然而,在网络上却很少见到有详细或者深刻的剖析论文.下面 ...
- Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究
Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: 反射的概念是由Smith在1982年首次提出的 ...
- Python之反射,正则
本节主要内容: 一. 反射: getattr hasattr setattr defattr 二. 补充模块中特殊的变量 三. 正则表达式 re模块 (一)反射: hasattr(object, na ...
- 关于PYTHON的反射,装饰的练习
从基本概念,简单例子才能慢慢走到高级一点的地方. 另外,PYTHON的函数式编程也是我很感兴趣的一点. 总体而言,我觉得OOP可以作大的框架和思路,FP能作细节实现时的优雅牛X. ~~~~~~~~~~ ...
- 详解python之反射机制
一.前言 def f1(): print('f1') def f2(): print('f2') def f3(): print('f3') def f4(): print('f4') a = 1 t ...
- 第六章:Python基础の反射与常用模块解密
本课主题 反射 Mapping 介绍和操作实战 模块介绍和操作实战 random 模块 time 和 datetime 模块 logging 模块 sys 模块 os 模块 hashlib 模块 re ...
- python 异常 反射
异常 反射 一.异常处理: AttributeError 试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x IOError 输入/输出异常:基本上是无法打开文件 ImportError ...
随机推荐
- c# 递归
递归 函数体内调用自身函数,直到符合某一条件时不再继续调用两个需要满足的条件1.有反复调用自身函数的过程2.有函数的出口,有不再继续执行的条件 练习: 1.用递归函数做n的阶乘. 2.一群羊赶到村庄去 ...
- 面试之servlet、过滤器、监听器
servlet.过滤器.监听器servlet是Java中WEB请求和响应的容器servlet的运行需要在类似tomcat容器中,一个 Web 应用对应一个 Context 容器,也就是 Servlet ...
- MyISAM表加字段的特殊方法
最近一个统计系统的大表需要加字段,表的引擎是myisam,表大小在3亿,物理文件在106G.想想都蛋疼.那么这种情况下怎么把字段撸上去呢? 1. 首先想到了<高性能MySQL>提到的直接更 ...
- linux同步系统时间
命令:ntpdate 路径:/usr/sbin/ntpdate 例子:ntpdate us.pool.ntp.org 查看日期时间命令:date 修改日期时间命令:date -s "2012 ...
- GsonUtils.java
package com.vcredit.ddcash.batch.util; import java.util.ArrayList;import java.util.List; import org. ...
- Maven学习 (四) 使用Nexus搭建Maven私服
为什么要搭建nexus私服,原因很简单,有些公司都不提供外网给项目组人员,因此就不能使用maven访问远程的仓库地址,所以很有必要在局域网里找一台有外网权限的机器,搭建nexus私服,然后开发人员连到 ...
- BizTalk 开发系列(四十一) BizTalk 2010 BAM 安装手记
使用64位系统可以支持更大的内存,现在服务器基本上都使用64位系统.微软从Windows Server 2008 R2开始服务器版的操作系统也只支持64位了,不过对于像BizTalk这种“繁杂的东西” ...
- profile
项目开发中,使用git最为版本控制工具,往往会建立开发分支.测试分支和生产分支. 各个分支的数据库url,所依赖的接口url可能不同,直接配置的话,在合并分支时往往出现冲突.使用profile可以有效 ...
- logback使用总结
filter: http://aub.iteye.com/blog/1110008 http://aub.iteye.com/blog/1101222 Logback Log4j的创始人Ceki Gü ...
- ThinkPHP 3.2.3 自动加载公共函数文件的方法
方法一.加载默认的公共函数文件 在 ThinkPHP 3.2.3 中,默认的公共函数文件位于公共模块 ./Application/Common 下,访问所有的模块之前都会首先加载公共模块下面的配置文件 ...