Python 反射

2019-02-20 00:46:29来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

一 反射

什么是反射?

  反射的概念由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
hasattr(object, name)
 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
getattr(object, name, default = node)
 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}
setattr(x, y, v)
 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': '雪峰路'}
delattr(x, y)

反射应用示例:

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
Ftp_Client.py
 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('其他的逻辑')
Ftp_user.py

  动态导入模块:

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
__getattr__
 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__
__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__
__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
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:20190218-学习python使用shelve遇到raise error, &quot;db type

下一篇:python json模块