面向对象之反射和其他内置方法
一、反射
1、概念:主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。简而言之,就是自身调用自身即可实现已定义的某一功能,以达到简化程序的作用。
2、python面向对象中的反射是指通过字符串的形式操作对象相关的属性。因为python中一切事物都是对象,所以都可以使用反射。一句话,就是通过字符串映射到对象的属性。
3、示例:
!/usr/bin/env python3 #-*- coding:utf-8 -*- # write by congcong# 反射:通过字符串映射到对象的属性 class People:def __init__(self,name,age):self.name = nameself.age = agedef study(self): # 绑定对象方法print('%s is studying now'%self.name) p1 = People('cc',21) print(p1.name) # cc # hasattr(obj,str) 判断字符串所对应的属性是否在指定对象中存在
print(hasattr(p1,'name')) # True print(hasattr(p1,'study')) # True print(hasattr(People,'study')) # True print(hasattr(People,'name')) # False # getattr(obj,str,None) 获取对象中字符串对应的属性,没有时返回None
print(getattr(p1,'name',None)) # cc print(getattr(p1,'study',None)) # <bound method People.study of <__main__.People object at 0x0000024C49773320>> print(getattr(People,'name',None)) # None print(getattr(People,'study',None)) # <function People.study at 0x000001AEE4128B70> # setattr(obj,str) # 设置属性,添加或修改属性
setattr(p1,'sex','male') setattr(p1,'age',22) setattr(People,'country','China') print(p1.__dict__) # {'name': 'cc', 'age': 22, 'sex': 'male'} print(People.__dict__) # {'__module__': '__main__', '__init__': <function People.__init__ at 0x00000164440C8AE8>, 'study': <function People.study at 0x00000164440C8B70>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None, 'country': 'China'} # delattr(obj,str) 删除属性
delattr(p1,'sex') delattr(People,'country') print(p1.__dict__) # {'name': 'cc', 'age': 22} print(People.__dict__) # {'__module__': '__main__', '__init__': <function People.__init__ at 0x0000021A437E8AE8>, 'study': <function People.study at 0x0000021A437E8B70>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
4、反射的好处
优点1:实现可插拔机制
可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能。
优点2:动态导入模块(基于反射当前模块成员)
python提供了一个特殊的方法:__import__(字符串参数)。
通过它,我们就可以实现类似的反射功能。__import__()方法会根据参数,动态的导入同名的模块。
import commonsdef run():inp = input("请输入您想访问页面的url: ").strip()modules, func = inp.split("/")obj = __import__("lib."
+
modules, fromlist
=
True
) # 注意fromlist参数if hasattr(obj, func):func = getattr(obj, func)func()else:print("404")if __name__ == '__main__':run()
请输入您想访问页面的url: commons/home 这是网站主页面! 请输入您想访问页面的url: account/find 这是一个查找功能页面!
5、反射的一个小例子
# 反射的应用 class Handle:def run(self):exit_flag = Falsewhile not exit_flag:user_in = input('>>:').strip()hand_cmd = user_in.split()if hasattr(self,hand_cmd[0]):func = getattr(self,hand_cmd[0])func(hand_cmd)elif user_in=='q':exit_flag=Trueelse:print('error input')def put(self,hand_cmd):print('putting now',hand_cmd)def get(self,hand_cmd):print('getting now',hand_cmd) f = Handle() f.run()
View Code
二、其它内置方法
1、isinstance(object,cls) 和 issubclass(sub,super)
<1> isinstance(object,cls) 检查是否是类cls的对象
class Func(object):pass obj = Func() print(isinstance(obj, Func)) # True
<2> issubclass(sub, super)检查sub类是否是 super 类的子类
class Foo(object):pass class Bar(Foo):pass print(issubclass(Bar, Foo)) # True
2、item系列
class Func():def __init__(self,name):self.name = namedef __getitem__(self, item): print('from getitem')return self.__dict__.get(item)def __setitem__(self, key, value): print('from setitem') self.__dict__[key] = value def __delitem__(self, key): print('from delitem') # print('del obj[key]时,执行')del self.__dict__[key] self.__dict__.pop(item) p1 = Func('cc') print(p1.__dict__) # {'name': 'cc'}# 查看属性 print(p1['name']) # from getitem cc 触发__getitem__ print(p1.name) # cc# 设置属性 # p1.sex = 'male' # 不会触发__setitem__ p1['sex'] = 'male' # from setitem 会触发__setitem__
p1['name'] = 'SC'p1['age'] = 21 print(p1.__dict__) # {'name': 'SC', 'sex': 'male', 'age': 21} # 删除属性 # del p1.sex # 不会触发__delitem__del p1.agedel p1['sex'] # 触发__delitem__,输出:from delitem
print(p1.__dict__) # {'name': 'SC'}
注意:<1> item系列方法, 查看p1['name'] 、设置p1['name']、del p1['name'] 才会分别触发 __getitem__、__setitem__和__delitem__内置方法,执行对应方法。
<2>能写成p1['name']的分为两种情况:
1、字典
2、def __setitem__(self, key, value):pass
3、attr系列
# __setattr__,__delattr__,__getattr__ class Fun:x=1def __init__(self,y):self.y = ydef __getattr__(self, item):print("---> from getattr:你寻找的属性不存在")def __setattr__(self, key, value):print("--->from setattr")# self.key = value #无限递归self.__dict__[key]=value # 正确姿势 def __delattr__(self, item):print("--->from delattr")# del self.item #无限递归self.__dict__.pop(item)# __setattr__添加/修改属性会触发它的执行 f1 = Fun(66) print(f1.__dict__) # --->from setattr {'y': 66} 因为重写了__setattr__,凡是赋值操作都会触发它的执行 f1.z = 666 print(f1.__dict__) # --->from setattr {'y': 66, 'z': 666}# __getattr__只有在使用点调用属性且属性不存在时才会触发 print(f1.y) # 66 print(f1.xx) # ---> from getattr:你寻找的属性不存在# __delattr__删除属性的时候会触发 f1.__dict__['aa'] = 6688 print(f1.__dict__) #{'y': 66, 'z': 666, 'aa': 6688}
del f1.aa # 触发__delattr__,输出: --->from delattr print(f1.__dict__) # {'y': 66, 'z': 666}
del f1.__dict__['y'] #未触发__delattr__print(f1.__dict__) # {'z': 666}
注意:对于 attr 系列内置方法,只有在使用点调用属性且属性不存在时才会触发__getattr__方法;
使用点方法添加/修改属性会触发__setattr__方法的执行;使用点方法删除属性会触发__delattr__方法。
4、__str__类定制
class Str:def __init__(self,name,age):self.name = nameself.age = agedef __str__(self):return '<name:%s age: %s>'%(self.name,self.age) # 必须有返回值 msg = Str('hello',999) print(msg) # <name:hello age: 999> 打印对象时触发__str__方法,实现定制化输出
5、__init__和__del__
# 回收操作系统的资源 class Open:def __init__(self,filename):print('open file now')self.filename = filenamedef __del__(self): # 相当于self.close()等关闭操作,在此方法中进行Python不能自动回收的资源回收操作print('回收系统资源') f = Open('settings.py') # 包含两部分操作,一是Python解释器开辟一块内存并赋给f,二是在系统硬盘层面打开了一个文件 print('End...') # 触发del f --> f.__del__(Python程序结束会自动回收程序中的变量,对象,但不能关闭系统资源) ''' open file now End... 回收系统资源 '''
转载于:https://www.cnblogs.com/schut/p/8648157.html
面向对象之反射和其他内置方法相关推荐
- python_day21面向对象的进阶(反射,内置方法,)
# 两个内置函数 *# 反射 *****# 内置方法 *** # 类(定义) # 静态属性 类属性(变量) 直接写在类中,全大写 # 动态属性 方法(函数) self # 类方法 @classmeth ...
- python全栈开发基础【第十七篇】面向对象反射和内置方法
一.静态方法(staticmethod)和类方法(classmethod) 类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性) 静态方法:让类里的方法直接被 ...
- python 面向对象_多态、内置方法、反射
内容: 1.接口思想 2.抽象类思想 3.多态 4.内置方法 5.反射 1.接口思想 建立关联的桥梁,方便管理代码 接口类:用来定义功能的类,位继承它的子类提供功能 该类的功能方法一般不需要实现体,实 ...
- python面向对象 : 反射和内置方法
一. 反射 1. isinstance()和issubclass() isinstance( 对象名, 类名) : 判断对象所属关系,包括父类 (注:type(对象名) is 类名 : 判断对象所属 ...
- issubclass和isinstance 反射 内置方法(魔术方法)
目录 issubclass 和 isinstance issubclass isinstance 反射 通过用户输入的key,value往对象中赋值 动态的往对象中放方法 动态的删除属性 动态删除对象 ...
- python反射和高阶内置方法
1.isinstance:判断对象和类的关系 #判断结果返回bool类型 class A:pass class B(A):pass a = A() print(isinstance(a,A)) #Tr ...
- Python 内置方法和属性应用:反射和单例
1. 前言 python除了丰富的第三方库外,本身也提供了一些内在的方法和底层的一些属性,大家比较常用的如dict.list.set.min.max.range.sorted等.笔者最近在做项目框架时 ...
- python内置类属性_Python内置方法和属性应用:反射和单例(推荐)
1. 前言 python除了丰富的第三方库外,本身也提供了一些内在的方法和底层的一些属性,大家比较常用的如dict.list.set.min.max.range.sorted等.笔者最近在做项目框架时 ...
- python getattr_Python 内置方法和属性应用:反射和单例
1. 前言 python除了丰富的第三方库外,本身也提供了一些内在的方法和底层的一些属性,大家比较常用的如dict.list.set.min.max.range.sorted等.笔者最近在做项目框架时 ...
最新文章
- data-参数说明(模态弹出窗的使用)
- python indexerror_python – “IndexError:位置索引器超出范围”,当它们明显没有时
- 虚拟机服务器编号怎么查看,查看虚拟机的服务器地址
- ActionScript 3.0 优化
- System.Diagnostics.Process.Start()用法详解
- jfinal-swagger让你的应用接口更加简单
- 【计算机网络】—— 差错编码(纠错编码)
- Eratosthenes筛法求素数
- Visual Studio 2010 Beta版包括InstallShield Limited Edition
- java基于springboot+vue的旧物置换网站
- QT6.1.2下载和安装教程
- 给宝宝做一个cocos免费游戏-故事和开始界面
- rasp 系统_RASP技术分析
- 一个人赶着鸭子去每个村庄卖,每经过一个 村子卖去所赶鸭子的一半又一只。 这样他经过了 七个村子后还剩 两只鸭子,问问他出发时共赶多少只鸭子?经过每个村子卖出多少只鸭子?
- Shiro框架学习笔记、整合Springboot、redis缓存
- [mysql] 变量、处理程序和流程控制
- 首屏加载从11s到1s,详解前端性能优化
- Office 365 Certification 考试心得
- 在Windows Embedded Standard中阻止安装提示和OOBE
- 如何设置火狐主页及将火狐新建的标签页也设置成主页
热门文章
- 虚拟化桌面初始化配置处理
- ibatis This SQL map does not contain a MappedStatement
- 在nginx中配置如何防止直接用ip访问服务器web server及server_name特性讲解
- 防红直连php,【源码资源】20新PHP网址缩短防封防红短网址生成系统
- atom上网本 安装linux,拆东墙补西墙?多数Atom上网本或将无法安装Windows 7
- qcustomplot删除一条曲线_被“谭卓”旗袍造型给惊艳,波波头搭配一条酒红色旗袍,华丽高贵...
- python编辑器_自学python第一课之下载安装编辑器
- 最初级且依赖于硬件的计算机语言是,计算机基础复习大纲(整理版).doc
- 13位数字转日期 oracle_12amp;13. 整数转罗马数字 - 中等amp;简单
- java并发编程之HappenBefore