Python 反射
2019-02-20 00:46:29来源:博客园 阅读 ()
一 反射
什么是反射?
反射的概念由smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在List和面向对象方面取得了成绩。
4个可以实现反射的函数
下列方法适用于类和对象
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 # 判断object中有没有一个name字符串对应的方法或属性 6 class BlackMedium: 7 feture = 'Ugly' 8 9 def __init__(self, name, addr): 10 self.name = name 11 self.addr = addr 12 13 def sell_hourse(self): 14 print('【%s】正在卖房子' % self.name) 15 16 def rent_hourse(self): 17 print('【%s】正在租房子' % self.name) 18 19 20 b1 = BlackMedium('alex', '雪峰路') # bl.name--->b1.__dic['name'] 21 print(hasattr(b1, 'name')) # True
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 # 判断object中有没有一个name字符串对应的方法或属性 6 class BlackMedium: 7 feture = 'Ugly' 8 9 def __init__(self, name, addr): 10 self.name = name 11 self.addr = addr 12 13 def sell_hourse(self): 14 print('【%s】正在卖房子' % self.name) 15 16 def rent_hourse(self): 17 print('【%s】正在租房子' % self.name) 18 19 20 b1 = BlackMedium('alex', '雪峰路') # bl.name--->b1.__dic['name'] 21 print(getattr(b1, 'name')) # alex
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 # 判断object中有没有一个name字符串对应的方法或属性 6 class BlackMedium: 7 feture = 'Ugly' 8 9 def __init__(self, name, addr): 10 self.name = name 11 self.addr = addr 12 13 def sell_hourse(self): 14 print('【%s】正在卖房子' % self.name) 15 16 def rent_hourse(self): 17 print('【%s】正在租房子' % self.name) 18 19 20 b1 = BlackMedium('alex', '雪峰路') # bl.name--->b1.__dic['name'] 21 setattr(b1, 'test', 123) 22 print(b1.test) # 123 23 print(b1.__dict__) # {'name': 'alex', 'addr': '雪峰路', 'test': 123}
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 # 判断object中有没有一个name字符串对应的方法或属性 6 class BlackMedium: 7 feture = 'Ugly' 8 9 def __init__(self, name, addr): 10 self.name = name 11 self.addr = addr 12 13 def sell_hourse(self): 14 print('【%s】正在卖房子' % self.name) 15 16 def rent_hourse(self): 17 print('【%s】正在租房子' % self.name) 18 19 20 b1 = BlackMedium('alex', '雪峰路') # bl.name--->b1.__dic['name'] 21 setattr(b1, 'test', 123) 22 print(b1.test) # 123 23 print(b1.__dict__) # {'name': 'alex', 'addr': '雪峰路', 'test': 123} 24 delattr(b1, 'test') # <==> del b1.test 25 print(b1.__dict__) # {'name': 'alex', 'addr': '雪峰路'}
反射应用示例:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 class FtpClient: 6 def __init__(self, addr): 7 print('正在连接Ftp') 8 self.addr = addr
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 from Ftp_Client import FtpClient 4 5 f1 = FtpClient('172,16,1,10') 6 7 if hasattr(f1, 'put'): 8 func_get = getattr(f1, 'put') 9 func_get() 10 else: 11 print('其他的逻辑')
动态导入模块:
1 # 示例一 2 from m1.t import test1 3 m = test1 # 获得顶级模块名 4 5 6 # 示例二 7 import importlib 8 m = importlib.import_module('字符串') # 定位到导入的那个模块
双下划线开头的attr方法
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 # 注:__getattr__ 调用一个不存在的对象会执行 5 class Foo: 6 x = 1 7 8 def __init__(self, y): 9 self.y = y 10 11 def __getattr__(self, item): 12 print('执行__getattr__') 13 14 15 f1 = Foo(10) 16 print(f1.y) # 10 17 print(f1.z) # 执行__getattr__;None
1 # 注:__delattr__ 删除操作会执行 2 class Foo: 3 x = 1 4 5 def __init__(self, y): 6 self.y = y 7 8 def __delattr__(self, item): 9 print('删除__delattr__') 10 11 12 f1 = Foo(10) 13 del f1.y # 删除__delattr__ 14 del f1.z # 删除变量不存在时,也会执行__delattr__;删除__delattr__
1 class Foo: 2 x = 1 3 4 def __init__(self, y): 5 self.y = y 6 7 def __setattr__(self, key, value): 8 print('执行__setattr__') 9 self.__dict__[key] = value 10 11 12 f1 = Foo(10) # 执行__setattr__
二 二次加工标准类型(包装)
包装:Python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识(其他的标准类型均可以通过下面的方式进行二次加工)。
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 4 5 class List(list): 6 def append(self, p_object): 7 if type(p_object) is str: 8 super().append(p_object) # <==> list.append(self, p_object) 9 else: 10 print('添加数据类型不是字符串') 11 12 def show_midille(self): # 求列表中间值 13 mid_index = int(len(self) / 2) 14 return self[mid_index] 15 16 17 l1 = List('hello world!') 18 # print(l1.show_midille()) # w 19 l1.append('123') 20 print(l1) # ['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd', '!', '123']
授权:授权是包装的一个特性,包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。
实现授权的关键点就是覆盖__getattr__方法
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import time 4 5 6 class openfile: 7 def __init__(self, filename, mode='r', encoding='utf-8'): 8 # self.filename = filename 9 self.file = open(filename, mode, encoding=encoding) 10 self.mode = mode 11 self.encoding = encoding 12 13 def write(self, line): 14 t = time.strftime('%Y-%m-%d %X') 15 time.sleep(1) 16 self.file.write('%s %s' % (t, line)) 17 18 def __getattr__(self, item): 19 # print(item, type(item)) # read <class 'str'> 20 # self.file.read 21 return getattr(self.file, item) 22 23 24 f1 = openfile('a.txt', 'w+') 25 # print(f1.file) 26 # print(f1.read) # 触发__getattr__;<built-in method read of _io.TextIOWrapper object at 0x000000C2ECCAAC18> 27 # f1.seek(1) 28 # print(f1.read()) 29 f1.write('cpu负载过高\n') 30 f1.write('内存剩余不足\n') 31 32 # a.txt内容 33 ''' 34 2019-02-17 21:30:15 cpu负载过高 35 2019-02-17 21:30:16 内存剩余不足 36 '''
原文链接:https://www.cnblogs.com/chenyanbin/p/10362857.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- python3基础之“术语表(2)” 2019-08-13
- python3 之 字符串编码小结(Unicode、utf-8、gbk、gb2312等 2019-08-13
- Python3安装impala 2019-08-13
- 小白如何入门 Python 爬虫? 2019-08-13
- python_字符串方法 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash