一、反射在类中的使用

反射就是通过字符串来操作类或者对象的属性

  • 反射本质就是在使用内置函数,其中反射有以下四个内置函数:

    1. hasattr:判断一个方法是否存在与这个类中
    2. getattr:根据字符串去获取obj对象里的对应的方法的内存地址,加"()"括号即可执行
    3. setattr:通过setattr将外部的一个函数绑定到实例中
    4. delattr:删除一个实例或者类中的方法
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class People:country = 'China'def __init__(self, name):self.name = namedef eat(self):print('%s is eating' % self.name)peo1 = People('nick')
print(hasattr(peo1, 'eat'))  # peo1.eat
True
print(getattr(peo1, 'eat'))  # peo1.eat
<bound method People.eat of <__main__.People object at 0x1043b9f98>>
print(getattr(peo1, 'xxxxx', None))
None
setattr(peo1, 'age', 18)  # peo1.age=18
print(peo1.age)
18
print(peo1.__dict__)
{'name': 'egon', 'age': 18}
delattr(peo1, 'name')  # del peo1.name
print(peo1.__dict__)
{'age': 18}

1.1 应用

需求:通过用户输入命令启动功能

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class Ftp:def __init__(self, ip, port):self.ip = ipself.port = portdef 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()
>>>: time
输入的命令不存在
>>>: time
输入的命令不存在
>>>: q
break

二、反射在模块中的使用

2.1 前言

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
# test.py
def f1():print('f1')def f2():print('f2')def f3():print('f3')def f4():print('f4')a = 1
import test as ssss.f1()
ss.f2()
print(ss.a)

我们要导入另外一个模块,可以使用import.现在有这样的需求,我动态输入一个模块名,可以随时访问到导入模块中的方法或者变量,怎么做呢?

imp = input(“请输入你想导入的模块名:”)
CC = __import__(imp) 這种方式就是通过输入字符串导入你所想导入的模块
CC.f1()  # 执行模块中的f1方法

上面我们实现了动态输入模块名,从而使我们能够输入模块名并且执行里面的函数。但是上面有一个缺点,那就是执行的函数被固定了。那么,我们能不能改进一下,动态输入函数名,并且来执行呢?

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
# dynamic.py
imp = input("请输入模块:")
dd = __import__(imp)
# 等价于import imp
inp_func = input("请输入要执行的函数:")f = getattr(dd, inp_func,None)  # 作用:从导入模块中找到你需要调用的函数inp_func,然后返回一个该函数的引用.没有找到就烦会Nonef()  # 执行该函数
请输入模块:time
请输入要执行的函数:time1560959528.6127071

上面我们就实现了,动态导入一个模块,并且动态输入函数名然后执行相应功能。

当然,上面还存在一点点小问题:那就是我的模块名有可能不是在本级目录中存放着。有可能是如下图存放方式:

|- day24|- lib|- common.py

那么这种方式我们该如何搞定呢?看下面代码:

dd = __import__("lib.text.commons")  # 这样仅仅导入了lib模块
dd = __import__("lib.text.commons", fromlist=True)  # 改用这种方式就能导入成功
# 等价于import config
inp_func = input("请输入要执行的函数:")
f = getattr(dd, inp_func)
f()

2.2 反射机制

上面说了那么多,到底什么是反射机制呢?

其实,反射就是通过字符串的形式,导入模块;通过字符串的形式,去模块寻找指定函数,并执行。利用字符串的形式去对象(模块)中操作(查找/获取/删除/添加)成员,一种基于字符串的事件驱动!

先来介绍四个内置函数:

2.2.1 getattr()

getattr()函数是Python自省的核心函数,具体使用大体如下:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
class A:def __init__(self):self.name = 'nick'# 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
2.2.2 hasattr(object, name)

说明:判断对象object是否包含名为name的特性(hasattr是通过调用getattr(ojbect, name)是否抛出异常来实现的)

2.2.3 setattr(object, name, value)

这是相对应的getattr()。参数是一个对象,一个字符串和一个任意值。字符串可能会列出一个现有的属性或一个新的属性。这个函数将值赋给属性的。该对象允许它提供。例如,setattr(x,“foobar”,123)相当于x.foobar = 123。

2.2.4 delattr(object, name)

与setattr()相关的一组函数。参数是由一个对象(记住python中一切皆是对象)和一个字符串组成的。string参数必须是对象属性名之一。该函数删除该obj的一个由string指定的属性。delattr(x, ‘foobar’)=del x.foobar

我们可以利用上述的四个函数,来对模块进行一系列操作.

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
r = hasattr(commons, xxx)  # 判断某个函数或者变量是否存在
print(r)setattr(commons, 'age', 18)  # 给commons模块增加一个全局变量age = 18,创建成功返回nonesetattr(commons, 'age', lambda a: a + 1)  # 给模块添加一个函数delattr(commons, 'age')  # 删除模块中某个变量或者函数

注意:getattr,hasattr,setattr,delattr对模块的修改都在内存中进行,并不会影响文件中真实内容。

2.3 应用

基于反射机制模拟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")

Python面向对象:反射(hasattr和getattr和setattr和delattr)相关推荐

  1. python hasattr()、getattr()、setattr()、delattr()函数

    Python hasattr().getattr().setattr().delattr()函数 hasattr()函数 hasattr()函数用于判断是否包含对应的属性:当然,对于Python的对象 ...

  2. python--基础知识点--反射机制——hasattr、getattr、setattr、delattr

    一.概念 反射:可以把字符串映射到实例的变量或者实例的方法然后可以去执行调用.修改等操作. getattr :获取指定字符串名称的对象属性或方法. setattr :为对象设置一个对象属性或方法. h ...

  3. Python学习: hasattr()、getattr()、setattr()函数简介

    一.hasattr(object, name) 判断object对象中是否存在name属性,当然对于python的对象而言,属性包含变量和方法:有则返回True,没有则返回False:需要注意的是na ...

  4. Python 反射机制之hasattr()、getattr()、setattr() 、delattr()函数

    反射机制 先看看我对Java中反射机制的通俗理解:反射之中包含了一个"反"的概念,所以要想解释反射就必须先从"正"开始解释,一般而言,当用户使用一个类的时候,应 ...

  5. Python3 中hasattr()、getattr()、setattr()、delattr()函数及示例代码数

    hasattr()函数 hasattr()函数用于判断是否包含对应的属性 语法: hasattr(object,name) 参数: object–对象 name–字符串,属性名 返回值: 如果对象有该 ...

  6. python中attr_python中hasattr()、getattr()、setattr()函数的使用

    引言: 在阅读高手写的代码时,有很多简写的形式,如果没有见过还真的看不太懂是什么意思,其中一个比较常用的就是getattr()用来调用一个类中的变量或者方法,相关联的hasattr().getattr ...

  7. python中hasattr()、getattr()、setattr()函数的使用

    在阅读高手写的代码时,有很多简写的形式,如果没有见过还真的看不太懂是什么意思,其中一个比较常用的就是getattr()用来调用一个类中的变量或者方法,相关联的hasattr().getattr().s ...

  8. python hasattr函数_Python3 hasattr()、getattr()、setattr()函数简介

    Python3 hasattr().getattr().setattr()函数简介 一.hasattr(object, name) 判断object对象中是否存在name属性,当然对于python的对 ...

  9. python中setattr用法_python中hasattr()、getattr()、setattr()函数的使用

    引言: 在阅读源码时,有很多简写的形式,其中一个比较常用的就是getattr()用来调用一个类中的变量或者方法,相关联的hasattr().getattr().setattr()函数的使用也一并学习了 ...

最新文章

  1. Linux各发行版流行度统计数据与排名
  2. WM_CHAR、WM_KEYDOWN和WM_SYSKEYDOWN消息
  3. dlib dll load failed 找不到指定的模块
  4. 871 最低加油次数
  5. mcafee安装是出现1920错误
  6. Android之利用SharedPreferences进行简单数据存储
  7. 程序员的修神之路是?
  8. 初探 Go 的编译命令执行过程
  9. 最小化安装的redhat/centos安装gnome桌面
  10. javafx 与java,java桌面应用程序和javafx有什么区别?
  11. 漂亮html表格页面模板,四款好看实用的CSS表格样式分享
  12. 一个实用的小工具——键盘映射KeyTweak
  13. AMD显卡超频显示器方法
  14. 计算机税率函数,2018最新按5000元个税Excel计算公式,帮你整理齐了!
  15. Win10 Microsoft Edge浏览器播放视频出现绿屏情况解决之一
  16. mysql如何重复数据合并_mysql合并重复数据
  17. c语言实现翻页,css3实现翻页卡片
  18. weather.com.cn的天气预报
  19. JSON解析工具----JSONPath基本使用
  20. kicad 输出Gerber文件

热门文章

  1. 蓝懿教育九月八日记录
  2. opencv imread
  3. 场效应晶体管内存 到底是谁发明的?
  4. 【修炼1】《序章》关于要写给谁看的问题
  5. android studio常用适配器,从ListView(Android Studio)的自定义适配器中的U...
  6. PP生产订单的BADI增强 WORKORDER_UPDATE
  7. ABAP动态生成内表的三种方法
  8. 活动的批输入监控ENV
  9. “埃尼阿克”背后的6个女孩
  10. 阿联酋是发达国家还是发展中国家