反射(hasattr和setattr和delattr)
反射(hasattr和setattr和delattr)
一、反射在类中的使用
反射就是通过字符串来操作类或者对象的属性, 反射本质就是在使用内置函数,其中反射有以下四个内置函数:
- hasattr:通过字符串,判断一个方法是否存在与这个类中
- getattr: 根据字符串去获取obj对象里的对应的方法的内存地址,加"()"括号即可执行(查找属性返回属性值,查找函数返回函数地址)
- setattr: 通过setattr将外部的一个函数绑定到实例中(通过字符串来设置属性或方法)
- delattr: 通过字符串删除一个实例或者类中的方法
class People:
country = 'China'
def __init__(self, name):
self.name = name
def eat(self):
print('%s is eating' % self.name)
peo1 = People('randy')
print(hasattr(peo1, 'eat')) # peo1.eat
True
# 获取对象中’'eat'函数
print(getattr(peo1, 'eat')) # peo1.eat
<bound method People.eat of <__main__.People object at 0x1043b9f98>>
# 获取对象中的‘xxxxx'
print(getattr(peo1, 'xxxxx', None))
None
# setattr(f, key, value)
setattr(peo1, 'age', 18) # peo1.age=18
print(peo1.age)
18
print(peo1.__dict__)
{‘name’: randy, ‘age’: 19}
# 删除对象中的name属性
f.name = 'randy'
print(f.__dict__)
del f.name
print(f.__dict__)
{'name': 'randy'}
{}
二、应用
class Ftp:
def __init__(self, ip, port):
self.ip = ip
self.port = port
def get(self):
print('GET function')
def put(self):
print('PUT function')
def run(self):
while True:
choice = input('>>>: ').strip()
if choice == 'q':
print('break')
break
# print(choice, type(choice))
# if hasattr(self, choice):
# method = getattr(self, choice)
# method()
# else:
# print('输入的命令不存在')
method = getattr(self, choice, None)
if method is None:
print('输入的命令不存在')
else:
method()
conn = Ftp('1.1.1.1', 23)
conn.run()
三、反射在模块中的使用
# test.py
def f1():
print('f1')
def f2():
print('f2')
def f3():
print('f3')
def f4():
print('f4')
a = 1
import test as ss
ss.f1()
ss.f2()
print(ss.a)
我们要导入另外一个模块,可以使用import.现在有这样的需求,我动态输入一个模块名,可以随时访问到导入模块中的方法或者变量,怎么做呢?
imp = input(“请输入你想导入的模块名:”)
CC = __import__(imp) 這种方式就是通过输入字符串导入你所想导入的模块
CC.f1() # 执行模块中的f1方法
上面我们实现了动态输入模块名,从而使我们能够输入模块名并且执行里面的函数。但是上面有一个缺点,那就是执行的函数被固定了。那么,我们能不能改进一下,动态输入函数名,并且来执行呢?
# dynamic.py
imp = input("请输入模块:")
dd = __import__(imp)
# 等价于import imp
inp_func = input("请输入要执行的函数:")
f = getattr(dd, inp_func,
None) # 作用:从导入模块中找到你需要调用的函数inp_func,然后返回一个该函数的引用.没有找到就返回None
f() # 执行该函数
输入模块:time
请输入要执行的函数:time
1560959528.6127071
上面我们就实现了,动态导入一个模块,并且动态输入函数名然后执行相应功能。
当然,上面还存在一点点小问题:那就是我的模块名有可能不是在本级目录中存放着。有可能是如下图存放方式:
dd = __import__("lib.text.commons") # 这样仅仅导入了lib模块
dd = __import__("lib.text.commons", fromlist=True) # 改用这种方式就能导入成功
# 等价于import config
inp_func = input("请输入要执行的函数:")
f = getattr(dd, inp_func)
f()
四、反射机制
上面说了那么多,到底什么是反射机制呢?
其实,反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!
4.1 getattr()
getattr()函数是Python自省的核心函数,具体使用大体如下:
class A:
def __init__(self):
self.name = 'ran'
# self.age='18'
def method(self):
print("method print")
a = A()
print(getattr(a, 'name',
'not find')) # 如果a 对象中有属性name则打印self.name的值,否则打印'not find'
print(getattr(a, 'age',
'not find')) # 如果a 对象中有属性age则打印self.age的值,否则打印'not find'
print(getattr(a, 'method', 'default')) # 如果有方法method,否则打印其地址,否则打印default
print(getattr(a, 'method', 'default')()) # 如果有方法method,运行函数并打印None否则打印default
4.2 hasattr(object, name)
说明:判断对象object是否包含名为name的特性(hasattr是通过调用getattr(ojbect, name)是否抛出异常来实现的)
4.3 setattr(object, name, value)
这是相对应的getattr()。参数是一个对象,一个字符串和一个任意值。字符串可能会列出一个现有的属性或一个新的属性。这个函数将值赋给属性的。该对象允许它提供。例如,setattr(x,“foobar”,123)相当于x.foobar = 123。
4.4 delattr(object, name)
与setattr()相关的一组函数。参数是由一个对象(记住python中一切皆是对象)和一个字符串组成的。string参数必须是对象属性名之一。该函数删除该obj的一个由string指定的属性。delattr(x, 'foobar')=del x.foobar
我们可以利用上述的四个函数,来对模块进行一系列操作.
r = hasattr(commons, xxx) # 判断某个函数或者变量是否存在
print(r)
setattr(commons, 'age', 18) # 给commons模块增加一个全局变量age = 18,创建成功返回none
setattr(commons, 'age', lambda a: a + 1) # 给模块添加一个函数
delattr(commons, 'age') # 删除模块中某个变量或者函数
注意:getattr,hasattr,setattr,delattr对模块的修改都在内存中进行,并不会影响文件中真实内容。
4.2 应用
基于反射机制模拟web框架路由
需求:比如我们输入<www.xxx.com/commons/f1> ,返回f1的结果。
# 动态导入模块,并执行其中函数
url = input("url: ")
target_module, target_func = url.split('/')
m = __import__('lib.' + target_module, fromlist=True)
inp = url.split("/")[-1] # 分割url,并取出url最后一个字符串
if hasattr(m, target_func): # 判断在commons模块中是否存在inp这个字符串
target_func = getattr(m, target_func) # 获取inp的引用
target_func() # 执行
else:
print("404")
反射(hasattr和setattr和delattr)的更多相关文章
- python -反射hasattr、setattr、delattr
login.py #!/usr/bin/dev python# coding:utf-8 def index(): print u'欢迎访问xx网站首页' def login(): print u'登 ...
- isinstance/type/issubclass的用法,反射(hasattr,getattr,setattr,delattr)
6.23 自我总结 面向对象的高阶 1.isinstance/type/issubclass 1.type 显示对象的类,但是不会显示他的父类 2.isinstance 会显示的对象的类,也会去找对象 ...
- python全栈开发day23-面向对象高级:反射(getattr、hasattr、setattr、delattr)、__call__、__len__、__str__、__repr__、__hash__、__eq__、isinstance、issubclass
一.今日内容总结 1.反射 使用字符串数据类型的变量名来操作一个变量的值. #使用反射获取某个命名空间中的值, #需要 #有一个变量指向这个命名空间 #字符串数据类型的名字 #再使用getattr获取 ...
- 反射getattr,hasattr,setattr,delattr
通过字符串映射或修改程序运行时的状态.属性.方法, 有以下4个方法 getattr(object, name_str, default=None) 根据字符串name_str去获取obj对象里的方法内 ...
- 反射(hasattr,getattr,delattr,setattr)
反射(hasattr,getattr,setattr,delattr) 反射在类中的使用 反射就是通过字符串来操作类或者对象的属性 反射本质就是在使用内置函数,其中反射有四个内置函数: hasattr ...
- python中hasattr, getattr,setattr及delattr四个方法
通过一个实例来说明,这四个函数的用法: 首先一个如下的一个简单的类: class Animal(object): def __init__(self,name, zone): self.name = ...
- python反射hasattr getattr setattr delattr
反射 : 是用字符串类型的名字 去操作 变量 相比于用eval('print(name)') 留有 安全隐患 反射 就没有安全问题 hasattr 语法: hasattr(object, name)o ...
- 反射hasattr; getattr; setattr; delattr
hasattr(obj,name_str):#判断一个对象obj里面是否有对应的name_str字符串的方法,返回True或者Falsegetattr(obj,name_str):#根据字符串去获取对 ...
- 反射(hasattr , getattr, setattr) 输入的字符串用来运行程序
当用户输入字符串时,不能够用来运行程序 1.使用 hasattr 找出输入的字符串是否在程序内 2.使用 getattr 返回找出字符串对应的函数的内存地址或者变量 3. 使用setattr 添加新的 ...
随机推荐
- JAXB工具
在JDK6之后,都自带了JAXB工具,所以在jdk类库与tomcat WEBAPP类库之间,会造成冲突 https://blog.csdn.net/iteye_13776/article/detail ...
- POJ - 1065 Wooden Sticks(贪心+dp+最长递减子序列+Dilworth定理)
题意:给定n个木棍的l和w,第一个木棍需要1min安装时间,若木棍(l’,w’)满足l' >= l, w' >= w,则不需要花费额外的安装时间,否则需要花费1min安装时间,求安装n个木 ...
- CSS - input 美化
input{ padding: 20px; width: 100%; height: 5vh; margin-bottom: 2vh; border-radius: 10vw; border: 0; ...
- Toolbar融入状态栏实现沉浸式遇到的问题
这里写一个纠结我一下午的问题,目的是写一个toolbar和状态栏相融合的沉浸式的样子,遇到各种各样的问题,还好最后慢慢解决了. 一.首先在活动中将状态栏设为透明 @Override protected ...
- 九、CI框架之将URI转为数组原型
一.输入以下代码,uri_to_assoc的参数默认从3开始 二.输出效果如下: 不忘初心,如果您认为这篇文章有价值,认同作者的付出,可以微信二维码打赏任意金额给作者(微信号:382477247)哦, ...
- SASS - 环境搭建
SASS – 简介 SASS – 环境搭建 SASS – 使用Sass程序 SASS – 语法 SASS – 变量 SASS- 局部文件(Partial) SASS – 混合(Mixin) SASS ...
- 2020PHP面试-网络篇
一.网络协议分层 OSI七层: 物理层.数据链路层.网络层.传输层.会话层.表示层.应用层. TCP/IP四(五)层 : 物理层(主要是光电信号的传输). 数据链路层(MAC地址.以太网协议).网络层 ...
- [安洵杯 2019]easy_serialize_php
0x00 知识点 PHP反序列化的对象逃逸 任何具有一定结构的数据,只要经过了某些处理而把自身结构改变,则可能会产生漏洞. 参考链接: https://blog.csdn.net/a3320315/a ...
- springboot--入门(了解springboot)
个人认为,springboot和maven差不多.maven方便我们管理jar包,而springboot帮助我们简化spring的配置. 未完,待续.......
- python counter、闭包、generator、解数学方程、异常
1.counter 2.闭包 3.generator 4.解数学方程 5.异常 1.python库——counter from collections import Counter breakfast ...