一、实现自省的四个函数

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

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

如果没有则返回False

2、getaddr  获取实例的属性

class BlackMedium:
feture="Ugly"
def __init__(self,name,addr):
self.name=name
self.addr=addr
def sell_house(self):
print("%s 正在卖房子,傻逼才买呢" %self.name)
def rent_house(self):
print("%s 正在租房子,傻逼才租呢" % self.name)
b1=BlackMedium("中原地产","北京通州梨园")
print(getattr(b1,"name"))#获取实例的数据属性
print(getattr(b1,"addr"))#获取实例的数据属性
func=getattr(b1,"sell_house")#获取实例的函数属性,赋值给func
func() C:\python35\python3.exe D:/pyproject/day26/反射.py 中原地产 北京通州梨园 中原地产 正在卖房子,傻逼才买呢

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

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

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

class BlackMedium:
feture="Ugly"
def __init__(self,name,addr):
self.name=name
self.addr=addr
def sell_house(self):
print("%s 正在卖房子,傻逼才买呢" %self.name)
def rent_house(self):
print("%s 正在租房子,傻逼才租呢" % self.name)
b1=BlackMedium("中原地产","北京通州梨园")
print(getattr(b1,"name"))#获取实例的数据属性
print(getattr(b1,"addr"))#获取实例的数据属性
print(getattr(b1,"sell_housesss",""))#获取实例的函数属性,赋值给func C:\python35\python3.exe D:/pyproject/day26/反射.py 中原地产 北京通州梨园 1111

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

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

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

class BlackMedium:
feture="Ugly"
def __init__(self,name,addr):
self.name=name
self.addr=addr
def sell_house(self):
print("%s 正在卖房子,傻逼才买呢" %self.name)
def rent_house(self):
print("%s 正在租房子,傻逼才租呢" % self.name)
b1=BlackMedium("中原地产","北京通州梨园")
setattr(b1,"func",lambda x:x+1)
setattr(b1,"func1",lambda self:self.name+"sb")
print(b1.__dict__)
print(b1.func)
print(b1.func(6))
print(b1.func1(b1)) C:\python35\python3.exe D:/pyproject/day26/反射.py {'func1': <function <lambda> at 0x0000000000D32400>, 'func': <function <lambda> at 0x0000000000D321E0>, 'addr': '北京通州梨园', 'name': '中原地产'} <function <lambda> at 0x0000000000D321E0> 7 中原地产sb

4、delattr    删除实例的属性

class BlackMedium:
feture="Ugly"
def __init__(self,name,addr):
self.name=name
self.addr=addr
def sell_house(self):
print("%s 正在卖房子,傻逼才买呢" %self.name)
def rent_house(self):
print("%s 正在租房子,傻逼才租呢" % self.name)
b1=BlackMedium("中原地产","北京通州梨园")
# b1.sb=True
setattr(b1,"sb",True)#给b1这个实例增加一个sb的属性,值为True
setattr(b1,"加油",111)
setattr(b1,"name","大sb")#如果之前有name的属性,会覆盖之前的属性值
print(b1.__dict__)#查看实例b1的属性字典
del b1.sb#删除b1的属性
del b1.加油#删除b1的属性
print(b1.__dict__) C:\python35\python3.exe D:/pyproject/day26/反射.py {'sb': True, 'addr': '北京通州梨园', '加油': 111, 'name': '大sb'} {'addr': '北京通州梨园', 'name': '大sb'}
class BlackMedium:
feture="Ugly"
def __init__(self,name,addr):
self.name=name
self.addr=addr
def sell_house(self):
print("%s 正在卖房子,傻逼才买呢" %self.name)
def rent_house(self):
print("%s 正在租房子,傻逼才租呢" % self.name)
b1=BlackMedium("中原地产","北京通州梨园")
# b1.sb=True
setattr(b1,"sb",True)#给b1这个实例增加一个sb的属性,值为True
setattr(b1,"加油",111)
setattr(b1,"name","大sb")#如果之前有name的属性,会覆盖之前的属性值
print(b1.__dict__)#查看实例b1的属性字典
# del b1.sb#删除b1的属性
# del b1.加油#删除b1的属性
delattr(b1,"sb")
print(b1.__dict__) C:\python35\python3.exe D:/pyproject/day26/反射.py {'sb': True, 'addr': '北京通州梨园', 'name': '大sb', '加油': 111} {'addr': '北京通州梨园', 'name': '大sb', '加油': 111}

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

5、反射的具体应用

gouguoqi负责开发ftp_client这个类,但是出去旅游去了,代码只写了一半儿

class FtpClient:
'ftp客户端,但是还么有实现具体的功能'
def __init__(self,addr):
print('正在连接服务器[%s]' %addr)
self.addr=addr 

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

from ftp_client import FtpClient

f1=FtpClient('1.1.1.1')
# f1.put()#由于人家类还写好,直接调用就报错了 if hasattr(f1,'put'):#所以先判断一下人家到底写好了没有
func_get=getattr(f1,'put')
func_get()
else:
print('其他的逻辑') C:\python35\python3.exe D:/pyproject/day26/miaoye使用者.py 正在连接服务器[1.1.1.1] 正在上传文件

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

gouguoqi的ftp_client

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

miaoye的

from ftp_client import FtpClient

f1=FtpClient('1.1.1.1')
# f1.put()#由于人家类还写好,直接调用就报错了 if hasattr(f1,'put'):#所以先判断一下人家到底写好了没有
func_get=getattr(f1,'put')
func_get()
else:
print('其他的逻辑') C:\python35\python3.exe D:/pyproject/day26/miaoye使用者.py 正在连接服务器[1.1.1.1] 正在上传文

这就叫做可插拔式设计

二、动态导入模块

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

module_t=__import__("m1.t")
print(module_t) C:\python35\python3.exe D:/pyproject/day26/动态模块导入.py <module 'm1' (namespace)> module_t=__import__("m1.t")
print(module_t)
module_t.t.test1() C:\python35\python3.exe D:/pyproject/day26/动态模块导入.py <module 'm1' (namespace)> test1 m=__import__("test")
print(m)

2、补充:

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

t模块中的内容

def test1():
print("test1")
def test2():
print("test2") from m1.t import *
test1()
test2() C:\python35\python3.exe D:/pyproject/day26/动态模块导入.py test1 test2

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

def test1():
print("test1")
def _test2():
print("test2") NameError: name 'test2' is not defined

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

from m1.t import test1,_test2
test1()
_test2() C:\python35\python3.exe D:/pyproject/day26/动态模块导入.py test1 test2

3、利用模块的方式   import importlib

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

module_t=__import__("m1.t")
print(module_t)
module_t.t.test1() import importlib
m=importlib.import_module("m1.t")
print(m)
m.test1()
m._test2() C:\python35\python3.exe D:/pyproject/day26/动态模块导入.py <module 'm1.t' from 'D:\\pyproject\\day26\\m1\\t.py'> test1 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. 我的Android之路——底部菜单栏的实现

    底部菜单栏的实现 底部菜单栏两种实现方法:ViewPager:可滑动的界面:Fragment:固定的界面. 首先,页面布局,在除去顶部toolbar之后,将主界面分为两部分,一部分为界面显示区,另一部 ...

  2. IT行业的创新的读后感

    一.什么是创新 创新是以新思维.新发明和新描述为特征的一种概念化过程.它原意有三层含义,第一,更新:第二,创造新的东西:第三,改变.创新是人类特有的认识能力和实践能力,是人类主观能动性的高级表现形式, ...

  3. 阅读<构建之法>第10、11、12章

    第10章 典型用户和场景 10.2 规格说明书 10.3 功能驱动的设计 问题:怎样写好spec?功能驱动设计的功能设计阶段怎样实现一个具体的功能? 第11章 软件设计与实现 11.2开发阶段的日常管 ...

  4. PAT 1061 判断题

    https://pintia.cn/problem-sets/994805260223102976/problems/994805268817231872 判断题的评判很简单,本题就要求你写个简单的程 ...

  5. Disabling Chrome cache for website development

    https://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development https://s ...

  6. React state状态

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  7. ionic2中如何使用自动生成器

    ionic generator是命令行的功能,ionic2自动帮我们创建应用程序,从而节省了大量的时间,并增加我们的速度来开发一个项目的关键部分. ionic generator使我们可以自动创建以下 ...

  8. 03 基于umi搭建React快速开发框架(封装列表增删改查)

    前言 大家在做业务系统的时候,很多地方都是列表增删改查,做这些功能占据了大家很长时间,如果我们有类似的业务,半个小时就能做出一套那是不是很爽呢. 这样我们就可以有更多的时间学习一些新的东西.我们这套框 ...

  9. std::binary_serach, std::upper_bound以及std::lower_bound

    c++二分查找的用法 主要是 std::binary_serach,  std::upper_bound以及std::lower_bound 的用法,示例如下: std::vector<int& ...

  10. BZOJ2017[USACO 2009 Nov Silver 1.A Coin Game]——DP+博弈论

    题目描述 农夫约翰的奶牛喜欢玩硬币游戏,因此他发明了一种称为“Xoinc”的两人硬币游戏. 初始时,一个有N(5 <= N <= 2,000)枚硬币的堆栈放在地上,从堆顶数起的第I枚硬币的 ...