首页 技术 正文
技术 2022年11月17日
0 收藏 912 点赞 3,406 浏览 2790 个字

反射

反射:通过字符串来映射到对象的属性

class People():
def __init__(self, name, age):
self.name = name
self.age = age def talk(self):
print('Name:%s,Age:%s' % (self.name, self.age))p = People('ysg', 21)# 判断 对象 中是否存在该属性,实际判断的是 p.__dict__ ['name']
print(hasattr(p, 'name')) # 结果:True# 取到 'name' 中的值
print(getattr(p, 'name', None)) # 结果:ysg
print(getattr(p, 'names', None)) # 结果:None
print(getattr(p, 'talk', None)) # <bound method People.talk of <__main__.People object at 0x0000020EDF705278>># 修改 'name' 中的值
setattr(p, 'name', 'ysging') # p.name = 'ysging'
print(p.name) # 结果:ysging# 删除 'name' 对象
delattr(p, 'age') # del p.age
print(p.__dict__) # 结果:{'name': 'ysging'}

有这样的需求:希望通过用户的输入内容来调用方法

例子

class People():
def __init__(self, name, age):
self.name = name
self.age = age def run(self):
while 1:
val = input('>>>')
if hasattr(self, val):
func = getattr(self, val, None)
func()
def talk(self):
print('Name:%s,Age:%s' % (self.name, self.age))p = People('ysg', 21)
p.run()# 结果
# >>>talk
# Name:ysg,Age:21

反射的好处:

好处一:实现可插拔机制

有俩程序员,一个lili,一个是egon,lili在写程序的时候需要用到egon所写的类,但是egon去跟女朋友度蜜月去了,还没有完成他写的类,lili想到了反射,使用了反射机制lili可以继续完成自己的代码,等egon度蜜月回来后再继续完成类的定义并且去实现lili想要的功能。

总之反射的好处就是,可以事先定义好接口,接口只有在被完成后才会真正执行,这实现了即插即用,这其实是一种‘后期绑定’,什么意思?即你可以事先把主要的逻辑写好(只定义接口),然后后期再去实现接口的功能

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

内置方法

isinstance(obj,cls) 检查是否 obj 是否是类 cls 的对象

class Foo():
passobj = Foo()
g = 123
print(isinstance(obj, Foo)) # True
print(isinstance(g, Foo)) # False

issubclass(sub, super) 检查 sub 类是否是 super 类的派生类

class Foo():
passclass A(Foo):
passclass B():
passprint(issubclass(A, Foo)) # True
print(issubclass(B, Foo)) # False

item 系列:把对象做成像字典的类型

class Foo():
def __init__(self, name):
self.name = name def __getitem__(self, item):
print('getitem...')
return self.__dict__.get(item) def __setitem__(self, key, value):
print('setitem...')
print(key,value) # name ysging
self.__dict__[key] = value def __delitem__(self, key):
del self.__dict__[key]f = Foo('ysg')
print(f.__dict__) # {'name': 'ysg'}# 取值
print(f['name']) # ysg# 设置
f['name'] = 'ysging'
print(f.name) # ysging# 删除
del f['name']
print(f.__dict__) # {}

__str__

一般情况下打印出为内存地址

class People():
def __init__(self, name, age):
self.name = name
self.age = agep = People('ysg', 22)
print(p) # <__main__.People object at 0x000002C168D952E8>

使用 __str__ 后,打印结果可以自定义

class People():
def __init__(self, name, age):
self.name = name
self.age = age def __str__(self):
return '<name:%s,age:%s>' % (self.name, self.age)p = People('ysg', 22)
print(p) # <name:ysg,age:22>

__del__:如果在类内部定义了一个 __del__ 方法,则会在对象被删除的时候先自动触发这个方法,再把对象删掉

python只会回收对象本身的资源,不会回收与对象相关的数据

class Open():
def __init__(self,file):
print('open file...')
self.file = file def __del__(self):
print('回收与对象相关的资源:self.close()') #这里可以写上与对象相关的数据,如:操作系统中的资源f = Open('config.py')
print('-------main-------')

析构方法,当对象在内存中被释放时,自动触发执行。

注:如果产生的对象仅仅只是python程序级别的(用户级),那么无需定义__del__,如果产生的对象的同时还会向操作系统发起系统调用,即一个对象有用户级与内核级两种资源,比如(打开一个文件,创建一个数据库链接),则必须在清除对象的同时回收系统资源,这就用到了__del__

典型的应用场景:

创建数据库类,用该类实例化出数据库链接对象,对象本身是存放于用户空间内存中,而链接则是由操作系统管理的,存放于内核空间内存中

当程序结束时,python只会回收自己的内存空间,即用户态内存,而操作系统的资源则没有被回收,这就需要我们定制__del__,在对象被删除前向操作系统发起关闭数据库链接的系统调用,回收资源

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,497
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,910
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,744
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,498
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,136
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,300