反射与二次加工标准类型

反射与二次加工标准类型

一、反射

反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。

有四个可以实现自省(反射)的函数,如下表所示:

函数名含义
hasattr(object,name)判断object中有没有一个name字符串对应的方法或属性
getattr(object,name, default=None)检查obj.__dict__中有没有name这个键值,有则不做任何处理,没有则报错
setattr(object,name,value)等价于object.name=value
delattr(object,name)等价于del object.name

各个函数具体代码实现:

class BlackMedium:feture = 'Ugly'def __init__(self,name,addr):self.name = nameself.addr = addrdef sell_hourse(self):print('%s正在卖房子' %self.name)def rent_hourse(self):print('%s正在租房子' %self.name)print(hasattr(BlackMedium,'feture'))   #结果为:True
b1 = BlackMedium('alex','厦门')
print(hasattr(b1,'name'))     #结果为:True
print(hasattr(b1,'sell_hourse'))    #结果为:Trueprint(getattr(b1,'name'))    #结果为:alex
g = getattr(b1,'sell_hourse')
g()    #结果为:alex正在卖房子
print(getattr(b1,'sell_hoursesafgsgr','没有这个属性'))     #结果为:没有这个属性

setattr(b1,'phone',18264894546)
print(b1.__dict__)     #结果为:{'name': 'alex', 'addr': '厦门', 'phone': 18264894546}
setattr(b1,'func',lambda x:x+1)
print(b1.__dict__)     #结果为:{'name': 'alex', 'addr': '厦门', 'phone': 18264894546, 'func': <function <lambda> at 0x000000000041C1E0>}
delattr(b1,'func')
print(b1.__dict__)    #结果为:{'name': 'alex', 'addr': '厦门', 'phone': 18264894546}

上述代码介绍了实现自省(反射)的函数。

反射的两个好处:

第一的好处:实现可插拔机制

假设程序员a与程序员b负责同一个项目,程序员a负责实现功能,而程序员b负责执行功能,那么程序员b在执行功能时发现程序员a的实现功能还未写入,这样就会出错,该如何解决这一问题?我们可以使用上面所学的反射来解决,具体代码如下:

#程序员a写的实现功能,写在ftp_client.py文件
class FtpClient:def __init__(self,addr):print('正在连接服务器%s' %addr)self.addr = addr# def put(self):        #假设这方法还没写,被程序员b调用#     print('正在上传文件')
#程序员b写的执行功能,写在ftp_bin.py文件
from ftp_client import FtpClientf1 = FtpClient('1.1.1.1')
#f1.put()   ftp_client文件还没有写这功能会报错,可以利用反射方式判断,如下所示if hasattr(f1,'put'):func_get = getattr(f1,'put')func_get()
else:print('不存在此方法,处理其它的逻辑')

上述代码利用反射方式判断,相当于事先定义接口,接口只有在被完成后才会真正执行,这实现了即插即用。

第二个好处:动态导入模块(基于反射当前模块成员)

假如你需要导入m1.py模块,即:

import m1
__import__('m1.tttt')   #这是解释器自己内部用的,它导入的就是m1模块
importlib.import_module('m1.tttt') #与上面这句效果一样

我们来了解类内置attr函数,分别是__setattr__、__getattr__、__delattr__。

__getattr__只有在使用点调用属性且属性不存在时候才会执行,具体如何实现请看下面代码:

class Foo:x = 1def __init__(self,y):self.y = ydef __getattr__(self, item):print('执行__getattr__')   #调用一个对象不存在时候才会执行
f1 = Foo(10)
print(f1.y)    #结果为:10
print(getattr(f1,'y'))   #结果为:10
f1.svdgsg     #结果为:执行__getattr__

__delattr__删除属性的时候才会执行,该属性不存在也会执行,具体实现如下代码所示:

class Foo:x = 1def __init__(self,y):self.y = ydef __delattr__(self, item):print('删除操作__delattr__')self.__dict__.pop(item)   #内置的
f1 = Foo(10)
del f1.y      #结果为:删除操作__delattr__
del f1.x      #结果为:删除操作__delattr__,报错

__setattr__在类被实例化、以及添加或修改属性的才会执行,代码如下:

class Foo:x = 1def __init__(self,y):self.y = ydef __setattr__(self,key,value):print('执行__setattr__')self.__dict__[key] = value    #内置的
f1 = Foo(10)     #结果为:执行__setattr__
print(f1.__dict__)    #结果为:{'y': 10}
f1.z = 2     #结果为:执行__setattr__
print(f1.__dict__)    #结果为:{'y': 10, 'z': 2}

二、二次加工标准类型

1.包装

Python为大家提供了标准数据类型,以及丰富的内置方法,其实在很多场景下我们都需要基于标准数据类型来定制我们自己的数据类型,新增/改写方法,这就用到了我们刚学的继承/派生知识。

假设利用list方法只能添加到字符串类型,具体代码如下:

class List(list):def append(self, item):if type(item) is str:super().append(item)    else:print('只能添加字符串类型')l1 = List('hello')
l1.append('alex')
print(l1)    #结果为:['h', 'e', 'l', 'l', 'o', 'alex']
l1.append(1646)    #结果为:只能添加字符串类型
print(l1)    #结果为:['h', 'e', 'l', 'l', 'o', 'alex']

上述代码在讲述包装一个类型通常是对已存在的类型的一些定制,这种做法可以新建、修改或删除原有产品的功能,其它的则保持原样。

2.授权

授权是包装的一个特性,授权的过程即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

假设我们想要修改文件的写操作,具体代码如下:

import datetime
class Open:def __init__(self,filename,mode='r',encoding='utf-8'):#self.filename = filenameself.file = open(filename,mode,encoding=encoding)self.mode = modeself.encoding = encodingdef write(self,line):    #将写操作加上当前时间t = datetime.datetime.now()self.file.write('%s %s' %(t,line))def __getattr__(self,item):return getattr(self.file,item)f1 = Open('a.txt','w+')
f1.write('1111111\n')   #执行类的write方法
f1.write('ssssss\n')
f1.write('hhhhh\n')
f1.seek(0)
print(f1.read())  #先在初始函数找,然后在类找,最后找到__getattr__方法,触发__getattr__

实现授权的关键点就是类中的__getattr__函数。

转载于:https://www.cnblogs.com/lzc69/p/11264038.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363363.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 8 StampedLocks与ReadWriteLocks和同步

同步部分就像访问您的岳父母。 您希望尽可能少出现。 关于锁定&#xff0c;规则是相同的–您想花费最短的时间在关键区域内获取锁定&#xff0c;以防止形成瓶颈。 锁定的核心语言惯用法一直是用于方法和离散块的synced关键字。 这个关键字实际上已硬连接到HotSpot JVM中。 我们…

MSN on 2/16/2009

转载于:https://www.cnblogs.com/zxlin25/archive/2009/02/16/1391207.html

开发微信小程序中SSL协议的申请、证书绑定、TLS 版本处理等

在上篇随笔《基于微信小程序的系统开发准备工作》介绍了开发微信小程序的一些前期的架构设计、技术路线 、工具准备等方面内容&#xff0c;本篇随笔继续这个步骤&#xff0c;逐步介绍我们实际开发过程中对SSL协议的申请及后期处理过程&#xff0c;包括证书的IIS端口绑定&#x…

POJ 3253 Fence Repair

POJ 3253 Fence Repair 题目链接&#xff1a;http://poj.org/problem?id3253 题目大意 农夫约翰想修理牧场周围的一小段篱笆。他测量了栅栏&#xff0c;发现他需要N(1≤N≤20,000)块木板&#xff0c;每块长度为整数Li(1≤Li≤50,000)。然后&#xff0c;他买了一块长木板&#…

【面向对象】对比JavaScript、Go、Ada、Python、C++、Java、PHP的访问限制。

在不同编程语言中&#xff0c;控制成员&#xff08;变量、方法、类等&#xff09;可见性的机制不尽相同。以下是对比JavaScript、Go、Ada、Python、C、Java、PHP所使用的访问限制关键字和约定&#xff1a; 一、JavaScript ### JavaScript访问限制 早期的JavaScript并没有类似…

C#各类访问权限,封装,修饰符

C#各类访问权限&#xff0c;封装&#xff0c;修饰符。 (1) Pubilc &#xff1a;任何公有成员可以被外部的类访问。(2) Private &#xff1a;只有同一个类中的函数可以访问它的私有成员。(3) Protected &#xff1a;该类内部和继承类中可以访问。(4) internal : 同一个程序集的对…

在Java 8中使用Stream API列出ZIP文件的内容

在Java 8 java.util.zip.ZipFile配备了stream方法&#xff0c;该方法可以非常轻松地浏览ZIP文件条目。 在此博客文章中&#xff0c;我将展示许多示例&#xff0c;这些示例显示了我们可以如何快速浏览ZIP文件条目。 注意&#xff1a;就本博客而言&#xff0c;我将一个GitHub存储…

tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法...

tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法 【标 题】&#xff1a;tomcat5下jsp出现getOutputStream() has already been called for this response异常的原因和解决方法【关键字】&#xff1a;tomcat5,jsp,getOutpu…

Web API应用架构设计分析(1)

Web API 是一种应用接口框架&#xff0c;它能够构建HTTP服务以支撑更广泛的客户端&#xff08;包括浏览器&#xff0c;手机和平板电脑等移动设备&#xff09;的框架&#xff0c; ASP.NET Web API 是一种用于在 .NET Framework 上构建 RESTful 应用程序的理想平台。本文主要以AS…

记手机端 下拉加载新数据

$(#container).unbind("scroll").bind(scroll,function(e){var sum this.scrollHeight - 5;console.log(sum)console.log($(this).scrollTop() $(this).height())if(sum <$(this).scrollTop() $(this).height()){ getmore();       }     }) $(#co…

一个切图仔的 CSS 笔记

1&#xff0c;flexbox~注意&#xff0c;设为 Flex 布局以后&#xff0c;子元素的float、clear和vertical-align属性将失效。 在ios8上要加上前缀 display: -webkit-box; display: -webkit-flex; display: -webkit-box; /* Chrome 4, Safari 3.1, iOS Safari 3.2 */ display: …

如何使用JPA Type Converter加密数据

几天前&#xff0c;我读了Bear Giles关于2012年使用JPA监听器进行数据库加密的有趣文章。他讨论了对加密解决方案的要求&#xff0c;并提供了JPA监听器的代码示例。 他的主要要求是&#xff1a; 提供不影响应用程序的透明加密&#xff0c; 能够在部署时添加加密&#xff0c; …

go语言的排序和去重

go语言的排序&#xff1a; https://blog.csdn.net/u010983881/article/details/52460998 go语言去重&#xff1a; https://blog.csdn.net/qq_27068845/article/details/77407358 通过构造set去重&#xff08;go中没有set&#xff09;&#xff1a; https://studygolang.com/arti…

MapXtreme2008中操作矢量符号和定制符号

本文部分说明内容摘自网络文章&#xff0c;经过本人在MapXtreme2008中编写相关的演示例子&#xff0c;详细说明如何操作MapXtreme2008提供的矢量符号和定制符号。 MapXtreme 在其安装过程中自动安装 10 种 MapInfo 特定的 TrueType 字体。这些字体为用户提供了字形符号选择&am…

指甲之指甲长期没有甲半月弧(二)

中医的精是构成人体的基本物质。精来源于先天的禀赋及后天饮食营养。中医认为&#xff0c;气不耗归于肝为血&#xff0c;血不耗归于肾为精&#xff0c;精不耗归于骨为髓。 半月痕正是人体精髓的窗口。而半月痕的变化&#xff0c;犹如汽车上的油表一样&#xff0c;它会告颂人体&…

编写干净的测试–从配置开始

很难为干净的代码找到一个好的定义&#xff0c;因为我们每个人都有自己的单词clean的定义。 但是&#xff0c;有一个似乎是通用的定义&#xff1a; 干净的代码易于阅读。 这可能会让您感到有些惊讶&#xff0c;但是我认为该定义也适用于测试代码。 使测试尽可能具有可读性是我…

集合类(二)

关于迭代器&#xff08;Iterator&#xff09;的两种迭代机制&#xff1a;fail-fast 和 fail-safe fail-fast 机制&#xff1a;遍历集合时&#xff0c;当集合结构被修改&#xff0c;会抛出Concurrent Modification Exception 触发条件&#xff1a;单线程在遍历过程修改&#xff…

jQuery-弹幕

该方法可能有bug&#xff0c;毕竟简单粗暴 <!DOCTYPE html><html> <head> <meta charset"UTF-8"> <title></title> <script type"text/javascript" src"js/jquery-1.11.0.js"></script> <s…

ubuntu下C编程,编译基础( 转)

buntu下C编程&#xff0c;编译基础 C 编程中相关文件后缀 .a静态库 (archive).cC源代码&#xff08;需要编译预处理&#xff09;.hC源代码头文件.iC源代码&#xff08;不需编译预处理&#xff09;.o对象文件.s汇编语言代码.so动态库单个源文件生成可执行程序 下面是一个简单的…

转载:97特瑞心得

单位里无聊打着玩的心得&#xff0c;写了段时间了&#xff0c;基本是哪天想到什么就打上去&#xff0c;狗屁不通的地方请大家包涵。97特瑞玩了有10年多了吧,97刚出来的时候就玩的特瑞&#xff0c;别人都八神&#xff0c;萝卜特&#xff0c;克拉克的时代我就坚持用特瑞&#xff…