Python之路- 反射&定制自己的数据类型
一.isinstance和issubclass
- isinstance(obj,cls)检查是否obj是否是类 cls 的对象
- issubclass(sub, super)检查sub类是否是 super 类的派生类
class Foo:
pass
class Bar(Foo):
pass
f = Foo()
b = Bar()
print(isinstance(f,Foo))
print(issubclass(Bar,Foo))
print(isinstance(Bar,Foo))
print(isinstance(b,Foo))
输出结果如下
True
True
False
True
二.反射和相关的内置函数
- 反射是指程序可以访问、检测和修改它自己本身状态或者行为的一种能力(自省)。
- 而在Python中,反射其实就是通过字符串的形式访问或者修改对象的属性。这里的对象是指一切对象,类本身也是一个对象。
class People:
country = 'china'
def __init__(self,name,sex):
self.name = name
self.sex = sex
def walk(self):
print('walk')
p1 = People('silver_bullet','male')
print(hasattr(p1,'name')) #hasattr(*args, **kwargs) 验证有没有该属性
print(getattr(p1,'sex')) #getattr(object, name, default=None) 获取一个属性,可以设置default
print(setattr(p1,'age',22)) #setattr(x, y, v) 设置一个属性,返回值为None,所以用下面get方法验证
print(getattr(p1,'age'))
print(delattr(p1,'age')) #delattr(x, 'y') is equivalent to del x.y 删除一个属性,返回值为None
# print(getattr(p1,'age')) #age属性已经被删除掉
setattr(p1,'show_name',lambda self:self.name+' is excellent')#增加一个函数属性
print(p1.show_name(p1))
模块级别的反射
import sys
xxx = 111
this_module = sys.modules[__name__] #获取当前模块
print(hasattr(this_module,'xxx'))
print(getattr(this_module,'xxx'))
setattr(this_module,'yyy','')
print(getattr(this_module,'yyy'))
反射的好处
实现可插拔机制。可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,即你可以事先把主要的逻辑写好(只定义接口), 然后后期再去实现接口的功能。
- 动态导入模块(基于反射当前模块成员)。
import importlib
t = importlib.import_module('time') #通过字符串的形式导入模块,推荐使用importlib
print(t.time()) #不推荐__import__(m),m为字符串,这个是python解释器自己使用的
三.内置函数(__attr__相关)
class Foo:
'内置函数__attr__的使用'
def __init__(self,name):
self.name = name #这个也会触发__setattr__的执行
def __setattr__(self, key, value): #给属性赋值都会触发__setattr__,把key和value都赋值,可以做类型判断,弥补python没有类型限制
self.__dict__[key] = value #直接在dict字典中添加相应的键值对即可,key和value都为字符串
print('from __setattr__')
def __delattr__(self, item): #del 操作会触发这个内置函数
self.__dict__.pop(item) #直接在dict字典中删除相应的键值对即可
print('from __delattr__',type(item))# type(item)--------->str
def __getattr__(self, item): #注意:属性获取不到,才会触发这个内置函数!!!
print('get__attr__---->{0},{1}'.format(item,type(item))) f = Foo('silver_bullet') #触发__init__里就有一个赋值,即会触发__settattr__
f.time = 555
print(f.__dict__)
print(f.time)
del f.time #触发__del__内置函数
print(f.__dict__)
f.xxx #这个才会触发__getattr__的执行,没有找到xxx的属性,而现在却没有报错
四.定制自己的数据类型
继承的方式
class my_list(list): #基于继承
def __init__(self,seq):
for i in seq:
if not isinstance(i,str):
raise TypeError('This is not a str list')
else:
super().append(i)
def append(self, object: str):
if not isinstance(object,str):
raise TypeError('must be str')
super().append(object)
@property
def mid_value(self):
mid_index = len(self)//2
return self[mid_index] l = my_list(['a'])
print(l)
l.append('')
print(l)
print(l.mid_value)
l.insert(0,4)
print(l)
授权的方式
class my_list(): #基于授权
def __init__(self,seq):
for i in seq:
if not isinstance(i,str):
raise TypeError('This is not a str list')
self.seq = list((seq)) #使用一个中间属性self.seq保存这个列表
def __str__(self): #override __str__,才能够打印列表的显示,否则打印的是一个对象地址
return str(self.seq)
def append(self, object: str): #重新定制这个append
if not isinstance(object,str):
raise TypeError('must be str')
self.seq.append(object) #实际上是在这里使用
@property
def mid_value(self): #定制一个属性,返回中间值。
mid_index = len(self.seq)//2
return self.seq[mid_index]
def __getattr__(self, item): #其余方法都使用list默认的
func = getattr(self.seq,item) #直接返回getattr的函数名
return func
def __getitem__(self, item): #加上以下三个item操作,才能够支持索引,切片,赋值和del删除
return self.seq[item]
def __setitem__(self, key, value):
self.seq[key] = value
def __delitem__(self, key):
self.seq.pop(key) l = my_list(['a'])
print(l)
l.append('')
print(l[1])
print(l.mid_value)
l.insert(0,4)
l[0]=''
print(l)
print(l[1:])
五.给日志文件加时间头
使用授权的方式重写open
import time
class Open:
'override File write'
def __init__(self,path,mode = 'r',encoding = 'GBK'):
self.fw = open(path,mode=mode,encoding=encoding) #这里要写成位置参数的形式,取到文件句柄赋值给self.f
def write(self,line):
now_time = time.strftime('%Y-%m-%d-%X') #字符串形式显示time时间
self.fw.write('{0}\n'.format(now_time)) #添加日志文件的时间头
self.fw.write(line) #写想要输入到文件里面的内容
def __getattr__(self, item): #不想要改写的地方定义在__getattr__中,找不到的属性会触发这个内置函数
func = getattr(self.fw,item) #通过getattr的方法,将函数名的入口地址获取到并且返回
return func f = Open('a.txt','w+') #触发__init__方法
for i in range(2):
f.write('11111111111\n')
time.sleep(0.5)
f.seek(0)
print(f.readlines())
Python之路- 反射&定制自己的数据类型的更多相关文章
- 我的python之路【第二篇】数据类型与方法
一.Python中有哪些数据类型 整型 在32位的系统中: 取值范围就是-(2^31) 到2^31-1 在64位系统中: 取值范围就是-(2^63) 到2^63-1 浮点型 布尔型 字符型 字符串 ...
- 百万年薪python之路 -- JS基础介绍及数据类型
JS代码的引入 方式1: <script> alert('兽人永不为奴!') </script> 方式2:外部文件引入 src属性值为js文件路径 <script src ...
- python之路--反射
一 . isinstance, type, issubclass isinstance 可以判断该对象是否是XXX家族体系中的(只能往上判断) class Base: pass class Foo(B ...
- 百万年薪python之路 -- MySQL数据库之 常用数据类型
MySQL常用数据类型 一. 常用数据类型概览 # 1. 数字: 整型: tinyint int bigint 小数: float: 在位数比较短的情况下不精确 double: 在位数比较长的情况下不 ...
- Python之路番外:PYTHON基本数据类型和小知识点
Python之路番外:PYTHON基本数据类型和小知识点 一.基础小知识点 1.如果一行代码过长,可以用续行符 \换行书写 例子 if (signal == "red") and ...
- 【python之路30】反射
一.反射 1.反射的基本介绍: 反射是所有程序的专有名词,在java,C#语言中都存在反射,那么什么是反射呢? python中 的反射概括来说:是通过字符串的形式导入模块,并通过字符串的形式去模块中寻 ...
- python之路 目录
目录 python python_基础总结1 python由来 字符编码 注释 pyc文件 python变量 导入模块 获取用户输入 流程控制if while python 基础2 编码转换 pych ...
- python 之路,Day11(上) - python mysql and ORM
python 之路,Day11 - python mysql and ORM 本节内容 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 创建数据库 ...
- Python之路【第八篇】:面向对象的程序设计
阅读目录 一 面向对象的程序设计的由来二 什么是面向对象的程序设计及为什么要有它三 类和对象3.1 什么是对象,什么是类3.2 类相关知识3.3 对象相关知识3.4 对象之间的交互3.5 类名称空间与 ...
随机推荐
- TensorBoard:Visualizing Learning 学习笔记
为了更方便的理解.调试和优化TF程序,我们可以使用TensorBoard(可视化工具).可以使用TensorBoard查看graph,绘制图表执行过程中的定量指标.TensorBoard是完全可配置的 ...
- JavaWeb之Filter过滤器
原本计划这一篇来总结JSP,由于JSP的内容比较多,又想着晚上跑跑步减减肥,所以今天先介绍Filter以及它的使用举例,这样的话还有些时间可以锻炼锻炼.言归正传,过滤器从字面理解她的话有拦网.过滤的功 ...
- RabbitMQ-从基础到实战(3)— 消息的交换
1.简介 在前面的例子中,每个消息都只对应一个消费者,即使有多个消费者在线,也只会有一个消费者接收并处理一条消息,这是消息中间件的一种常用方式.还有另外一种方式,生产者生产一条消息,广播给所有的消费者 ...
- Logistic Regression理论总结
简述: 1. LR 本质上是对正例负例的对数几率做线性回归,因为对数几率叫做logit,做的操作是线性回归,所以该模型叫做Logistic Regression. 2. LR 的输出可以看做是一种可能 ...
- iOS开发之应用沙盒
1.应用沙盒概述 每个iOS应用都有自己的应用沙盒(应用沙盒就是文件系统目录),与其他文件系统隔离.应用必须待在自己的沙盒里,其他应用不能访问该沙盒. 应用沙盒的文件系统目录,如下图所示(假设应用的名 ...
- React中使用CSSTransitionGroup插件实现轮播图
动画效果,是一个页面上必不可少的功能,学习一个新的东西,当然就要学习,如何用新的东西,用它的方法去实现以前的东西啦.今天呢,我就在这里介绍一个试用react-addons-css-transition ...
- DPDK QoS之分层调度器
原创翻译,转载请注明出处. 分层调度器的时机主要体现在TX侧,正好在传递报文之前.它的主要目的是在每个网络节点按照服务级别协议来对不同的流量分类和对不同的用户的报文区分优先级并排序. 一.概述分层调度 ...
- javaScript对象学习笔记(一)
一.什么是对象 对象: JavaScript的一种基本数据类型 对象是属性的无序集合,每个属性都是一个名/值对 JavaScript中的事物都是对象:字符串.数值.数组.函数... JavaScrip ...
- 自适应滤波:奇异值分解SVD
作者:桂. 时间:2017-04-03 19:41:26 链接:http://www.cnblogs.com/xingshansi/p/6661230.html 声明:欢迎被转载,不过记得注明出处哦 ...
- 性能测试培训:WebSocket协议的接口性能之Jmeter
性能测试培训:WebSocket协议的接口性能之Jmeter poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.poptest测试开 ...