一、实现自省的四个函数

1、hasattr判断一个对象中有没有一个name字符串对应的方法或属性

  1. class BlackMedium:
  2. feture="Ugly"
  3. def __init__(self,name,addr):
  4. self.name=name
  5. self.addr=addr
  6. def sell_house(self):
  7. print("%s 正在卖房子,傻逼才买呢" %self.name)
  8. def rent_house(self):
  9. print("%s 正在租房子,傻逼才租呢" % self.name)
  10. b1=BlackMedium("中原地产","北京通州梨园")
  11. #b1.name---->b1.__dic__["name"]
  12. print(hasattr(b1,"name"))#就是检测实例的属性字典里面有没有name这个key
  13. print(hasattr(b1,"sell_house"))#但是b1的属性字典里面没有sell_house,也是True
  14. #所以hasattr是检查实例到底能不能调用这个属性,能调用就True
  15.  
  16. C:\python35\python3.exe D:/pyproject/day26/反射.py
  17.  
  18. True
  19.  
  20. True

如果没有则返回False

2、getaddr  获取实例的属性

  1. class BlackMedium:
  2. feture="Ugly"
  3. def __init__(self,name,addr):
  4. self.name=name
  5. self.addr=addr
  6. def sell_house(self):
  7. print("%s 正在卖房子,傻逼才买呢" %self.name)
  8. def rent_house(self):
  9. print("%s 正在租房子,傻逼才租呢" % self.name)
  10. b1=BlackMedium("中原地产","北京通州梨园")
  11. print(getattr(b1,"name"))#获取实例的数据属性
  12. print(getattr(b1,"addr"))#获取实例的数据属性
  13. func=getattr(b1,"sell_house")#获取实例的函数属性,赋值给func
  14. func()
  15.  
  16. C:\python35\python3.exe D:/pyproject/day26/反射.py
  17.  
  18. 中原地产
  19.  
  20. 北京通州梨园
  21.  
  22. 中原地产 正在卖房子,傻逼才买呢

如果需要获取的实例的属性没有的话就报错了

  1. class BlackMedium:
  2. feture="Ugly"
  3. def __init__(self,name,addr):
  4. self.name=name
  5. self.addr=addr
  6. def sell_house(self):
  7. print("%s 正在卖房子,傻逼才买呢" %self.name)
  8. def rent_house(self):
  9. print("%s 正在租房子,傻逼才租呢" % self.name)
  10. b1=BlackMedium("中原地产","北京通州梨园")
  11. print(getattr(b1,"name"))#获取实例的数据属性
  12. print(getattr(b1,"addr"))#获取实例的数据属性
  13. func=getattr(b1,"sell_house11111111111111")#获取实例的函数属性,赋值给func
  14. func()
  15.  
  16. AttributeError: 'BlackMedium' object has no attribute 'sell_house11111111111111'

可以加一个默认的参数,如果getaddr获取的属性不存在的话就返回你定义的那个

  1. class BlackMedium:
  2. feture="Ugly"
  3. def __init__(self,name,addr):
  4. self.name=name
  5. self.addr=addr
  6. def sell_house(self):
  7. print("%s 正在卖房子,傻逼才买呢" %self.name)
  8. def rent_house(self):
  9. print("%s 正在租房子,傻逼才租呢" % self.name)
  10. b1=BlackMedium("中原地产","北京通州梨园")
  11. print(getattr(b1,"name"))#获取实例的数据属性
  12. print(getattr(b1,"addr"))#获取实例的数据属性
  13. print(getattr(b1,"sell_housesss",""))#获取实例的函数属性,赋值给func
  14.  
  15. C:\python35\python3.exe D:/pyproject/day26/反射.py
  16.  
  17. 中原地产
  18.  
  19. 北京通州梨园
  20.  
  21. 1111

3、setaddr给对象(实例)设置属性

  1. class BlackMedium:
  2. feture="Ugly"
  3. def __init__(self,name,addr):
  4. self.name=name
  5. self.addr=addr
  6. def sell_house(self):
  7. print("%s 正在卖房子,傻逼才买呢" %self.name)
  8. def rent_house(self):
  9. print("%s 正在租房子,傻逼才租呢" % self.name)
  10. b1=BlackMedium("中原地产","北京通州梨园")
  11. # b1.sb=True
  12. setattr(b1,"sb",True)#给b1这个实例增加一个sb的属性,值为True
  13. setattr(b1,"加油",111)
  14. setattr(b1,"name","大sb")#如果之前有name的属性,会覆盖之前的属性值
  15. print(b1.__dict__)#查看实例b1的属性字典
  16.  
  17. C:\python35\python3.exe D:/pyproject/day26/反射.py
  18.  
  19. {'name': '大sb', 'sb': True, '加油': 111, 'addr': '北京通州梨园'}

用setaddr给对象(实例)设置函数属性

  1. class BlackMedium:
  2. feture="Ugly"
  3. def __init__(self,name,addr):
  4. self.name=name
  5. self.addr=addr
  6. def sell_house(self):
  7. print("%s 正在卖房子,傻逼才买呢" %self.name)
  8. def rent_house(self):
  9. print("%s 正在租房子,傻逼才租呢" % self.name)
  10. b1=BlackMedium("中原地产","北京通州梨园")
  11. setattr(b1,"func",lambda x:x+1)
  12. setattr(b1,"func1",lambda self:self.name+"sb")
  13. print(b1.__dict__)
  14. print(b1.func)
  15. print(b1.func(6))
  16. print(b1.func1(b1))
  17.  
  18. C:\python35\python3.exe D:/pyproject/day26/反射.py
  19.  
  20. {'func1': <function <lambda> at 0x0000000000D32400>, 'func': <function <lambda> at 0x0000000000D321E0>, 'addr': '北京通州梨园', 'name': '中原地产'}
  21.  
  22. <function <lambda> at 0x0000000000D321E0>
  23.  
  24. 7
  25.  
  26. 中原地产sb

4、delattr    删除实例的属性

  1. class BlackMedium:
  2. feture="Ugly"
  3. def __init__(self,name,addr):
  4. self.name=name
  5. self.addr=addr
  6. def sell_house(self):
  7. print("%s 正在卖房子,傻逼才买呢" %self.name)
  8. def rent_house(self):
  9. print("%s 正在租房子,傻逼才租呢" % self.name)
  10. b1=BlackMedium("中原地产","北京通州梨园")
  11. # b1.sb=True
  12. setattr(b1,"sb",True)#给b1这个实例增加一个sb的属性,值为True
  13. setattr(b1,"加油",111)
  14. setattr(b1,"name","大sb")#如果之前有name的属性,会覆盖之前的属性值
  15. print(b1.__dict__)#查看实例b1的属性字典
  16. del b1.sb#删除b1的属性
  17. del b1.加油#删除b1的属性
  18. print(b1.__dict__)
  19.  
  20. C:\python35\python3.exe D:/pyproject/day26/反射.py
  21.  
  22. {'sb': True, 'addr': '北京通州梨园', '加油': 111, 'name': '大sb'}
  23.  
  24. {'addr': '北京通州梨园', 'name': '大sb'}
  1. class BlackMedium:
  2. feture="Ugly"
  3. def __init__(self,name,addr):
  4. self.name=name
  5. self.addr=addr
  6. def sell_house(self):
  7. print("%s 正在卖房子,傻逼才买呢" %self.name)
  8. def rent_house(self):
  9. print("%s 正在租房子,傻逼才租呢" % self.name)
  10. b1=BlackMedium("中原地产","北京通州梨园")
  11. # b1.sb=True
  12. setattr(b1,"sb",True)#给b1这个实例增加一个sb的属性,值为True
  13. setattr(b1,"加油",111)
  14. setattr(b1,"name","大sb")#如果之前有name的属性,会覆盖之前的属性值
  15. print(b1.__dict__)#查看实例b1的属性字典
  16. # del b1.sb#删除b1的属性
  17. # del b1.加油#删除b1的属性
  18. delattr(b1,"sb")
  19. print(b1.__dict__)
  20.  
  21. C:\python35\python3.exe D:/pyproject/day26/反射.py
  22.  
  23. {'sb': True, 'addr': '北京通州梨园', 'name': '大sb', '加油': 111}
  24.  
  25. {'addr': '北京通州梨园', 'name': '大sb', '加油': 111}

上面这四种attr都是在自己这里找,使用它们来实现自省的功能,就是自我反省,自我检查的意思,从自己这里找

5、反射的具体应用

  1. gouguoqi负责开发ftp_client这个类,但是出去旅游去了,代码只写了一半儿
  2.  
  3. class FtpClient:
  4. 'ftp客户端,但是还么有实现具体的功能'
  5. def __init__(self,addr):
  6. print('正在连接服务器[%s]' %addr)
  7. self.addr=addr 

miaoye负责一个其他的类,但是跟gouguoqi是一个团队的,虽然ftp_client没有写好,但是很不影响miaoye编写代码

  1. from ftp_client import FtpClient
  2.  
  3. f1=FtpClient('1.1.1.1')
  4. # f1.put()#由于人家类还写好,直接调用就报错了
  5.  
  6. if hasattr(f1,'put'):#所以先判断一下人家到底写好了没有
  7. func_get=getattr(f1,'put')
  8. func_get()
  9. else:
  10. print('其他的逻辑')
  11.  
  12. C:\python35\python3.exe D:/pyproject/day26/miaoye使用者.py
  13.  
  14. 正在连接服务器[1.1.1.1]
  15.  
  16. 正在上传文件

过了半年,gouguoqi度假回来了,写好了ftp_clent这个类,miaoye那里的代码都不用动,直接就可以用了

gouguoqi的ftp_client

  1. class FtpClient:
  2. 'ftp客户端,但是还么有实现具体的功能'
  3. def __init__(self,addr):
  4. print('正在连接服务器[%s]' %addr)
  5. self.addr=addr
  6. def put(self):
  7. print('正在上传文件')

miaoye的

  1. from ftp_client import FtpClient
  2.  
  3. f1=FtpClient('1.1.1.1')
  4. # f1.put()#由于人家类还写好,直接调用就报错了
  5.  
  6. if hasattr(f1,'put'):#所以先判断一下人家到底写好了没有
  7. func_get=getattr(f1,'put')
  8. func_get()
  9. else:
  10. print('其他的逻辑')
  11.  
  12. C:\python35\python3.exe D:/pyproject/day26/miaoye使用者.py
  13.  
  14. 正在连接服务器[1.1.1.1]
  15.  
  16. 正在上传文

这就叫做可插拔式设计

二、动态导入模块

1、__import__导入的只导入到顶级,就是导入了m1,

  1. module_t=__import__("m1.t")
  2. print(module_t)
  3.  
  4. C:\python35\python3.exe D:/pyproject/day26/动态模块导入.py
  5.  
  6. <module 'm1' (namespace)>
  7.  
  8. module_t=__import__("m1.t")
  9. print(module_t)
  10. module_t.t.test1()
  11.  
  12. C:\python35\python3.exe D:/pyproject/day26/动态模块导入.py
  13.  
  14. <module 'm1' (namespace)>
  15.  
  16. test1
  17.  
  18. m=__import__("test")
  19. print(m)

2、补充:

把t模块中的所有的方法都导入过来

t模块中的内容

  1. def test1():
  2. print("test1")
  3. def test2():
  4. print("test2")
  5.  
  6. from m1.t import *
  7. test1()
  8. test2()
  9.  
  10. C:\python35\python3.exe D:/pyproject/day26/动态模块导入.py
  11.  
  12. test1
  13.  
  14. test2

那我们把t模块中的test2前面加个下划线,变为私有属性之后import *就不能导入了

  1. def test1():
  2. print("test1")
  3. def _test2():
  4. print("test2")
  5.  
  6. NameError: name 'test2' is not defined

但是我们可以换种导入的方式,就可以正常导入了

  1. from m1.t import test1,_test2
  2. test1()
  3. _test2()
  4.  
  5. C:\python35\python3.exe D:/pyproject/day26/动态模块导入.py
  6.  
  7. test1
  8.  
  9. test2

3、利用模块的方式   import importlib

这种方式直接就可以导入到t了。而不是下面这样

  1. module_t=__import__("m1.t")
  2. print(module_t)
  3. module_t.t.test1()
  4.  
  5. import importlib
  6. m=importlib.import_module("m1.t")
  7. print(m)
  8. m.test1()
  9. m._test2()
  10.  
  11. C:\python35\python3.exe D:/pyproject/day26/动态模块导入.py
  12.  
  13. <module 'm1.t' from 'D:\\pyproject\\day26\\m1\\t.py'>
  14.  
  15. test1
  16.  
  17. test2

反射attr以及模块动态导入的更多相关文章

  1. 如何实现 React 模块动态导入

    如何实现 React 模块动态导入 React 模块动态导入 代码分割 webpack & code splitting https://reactjs.org/docs/code-split ...

  2. python 反射 动态导入模块 类attr属性

    1.反射 hasattr getattr delattr setattr 优点:事先定义好接口,接口只有在被完成后才能真正执行,这实现了即插即用,这其实是一种“后期绑定”,即先定义好接口, 然后是再去 ...

  3. 封装,封装的原理,Property ,setter ,deleter,多态,内置函数 ,__str__ , __del__,反射,动态导入模块

    1,封装 ## 什么是封装 what 对外隐藏内部的属性,以及实现细节,并给外部提供使用的接口 学习封装的目的:就是为了能够限制外界对内部数据的方法 注意 :封装有隐藏的意思,但不是单纯的隐藏 pyt ...

  4. day26 封装、多态、内置函数、反射、动态导入

    今日内容 1.封装 什么是封装? 封装从字面意思上看就只将某种东西封起来装好,当我们代码中的某些方法与属性不想让外界进行访问时,就对这些属性进行特殊的处理,使这种属性或者方法不能被外界直接进行访问或者 ...

  5. python面向对象反射-框架原理-动态导入-元类-自定义类-单例模式-项目的生命周期-05

    反射 reflect 反射(reflect)其实是反省,自省的意思 反省:指的是一个对象应该具备可以检测.修改.增加自身属性的能力 反射:通过字符串获取对象或者类的属性,进行操作 设计框架时需要通过反 ...

  6. Python 实现接口类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)

    实现接口类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...

  7. python之路(9)反射、包装类、动态模块导入

    目录 反射 利用继承二次包装标准类 利用授权二次包装标准类 动态模块导入 反射 python提供自省的四个方法: hasattr(object,name)  判断object中有没有有个name字符串 ...

  8. Python 实现抽象类的两种方式+邮件提醒+动态导入模块+反射(参考Django中间件源码)

    实现抽象类的两种方式 方式一 from abc import ABCMeta from abc import abstractmethod class BaseMessage(metaclass=AB ...

  9. python_反射:动态导入模块

    官方推荐方法: test_mod.py def hi(): print('Hi') test.py import importlib q = importlib.import_module('test ...

随机推荐

  1. QT 窗口置顶功能

    Qt中,保持窗口置顶的设置为: Qt::WindowFlags m_flags = windowFlags(); setWindowFlags(m_flags | Qt::WindowStaysOnT ...

  2. 关于HashMap和Hashtable的区别

    Hashtable的应用非常广泛,HashMap是新框架中用来代替Hashtable的类,也就是说建议使用HashMap,不要使用Hashtable.可能你觉得Hashtable很好用,为什么不用呢? ...

  3. 简话h5唤起本地app

    在没接触这个功能之前,查询各种文档后也只是似懂非懂,做过之后,发现其实很简单,简言之就是通过一个iframe或者a标签来跳转app端提供的URL schema(至于这个URL schema的组成格式, ...

  4. 实战框架ABP

    abp及实战框架概述 接触abp也快一年了,有过大半年的abp项目开发经验,目前项目中所用的abp框架版本为0.10.3,最新的abp框架已经到了1.4,并且支持了asp.net core.关于abp ...

  5. Android中加解密算法大全

    Base64编码 Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,本质上是一种将二进制数据转成文本数据的方案,对于非二进制数据,是先将其转换成二进制形式,然后每连续6比特(2的6次 ...

  6. ModSecurity is an open source, cross-platform web application firewall (WAF) module.

    http://www.modsecurity.org/ ModSecurity is an open source, cross-platform web application firewall ( ...

  7. 被辞退时N+1的说法

    “N+”,指在这家公司工作了N年,赔偿N个月的上年平均工资,再加上1个月“代通知金”. N的上限时12: 上年平均工资的上限是工作所在城市平均工资的三倍. StudyFrom知乎 所以很明显能够算出来 ...

  8. SQLSERVER 2014 内存优化表相关

    更新了SP2的补丁能够解决  不能收缩日志文件的bug了. 但是因为已经不用内存优化表了, 所以想着能够删除内存优化表的file group 但是发现 很难删除 先说结论: 以下是针对内存优化文件组的 ...

  9. [转帖] testin 安全测试要点

  10. [转帖]论iPhone处理器十年进化史

    论iPhone处理器十年进化史 导读: 今天,苹果发布了最新一代的iPhone,作为新一代的旗舰,新手机的功能承载了苹果对未来的希望和消费者的期待.但从我们半导体人看来更关注的是内部技术的演变,尤其是 ...