




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第Python3通过字符串访问和修改局部变量的方法实例目录技术背景读取和修改局部变量读取和修改全局变量读取和修改成员变量总结概要参考链接
技术背景
在Python中定义一个函数时,就会把变量空间划分为全局变量(global)与局部变量(local),如果是定义在一个类的成员函数中,那么就还有额外的成员变量(self)空间。那么,如果在实际操作中,想把这几种不同的变量空间做一个分离的话,有没有办法呢?
读取和修改局部变量
首先来看一下局部变量的读取,一般有locals()、vars()和sys._getframe(0).f_code.co_varnames这几种方法,另外有一种sys._getframe(0).f_locals的方法,其实等价于locals(),相关的实现代码如下:
x=0
classObj:
def__init__(self,y):
self.func(y)
deffunc(y,z=1):
m=2
print(locals())
print(vars())
print(__import__('sys')._getframe(0).f_code.co_varnames)
if__name__=='__main__':
Obj(2)
该代码的运行结果如下:
{self:__main__.Objobjectat0x7f5cf5e74e50,y:2,z:1,m:2}
{self:__main__.Objobjectat0x7f5cf5e74e50,y:2,z:1,m:2}
(self,y,z,m)
在vars方法不加具体变量名的时候,就是等价于locals方法,两者返回的结果都是字典格式。如果是一个类中的成员函数下执行locals或者vars,会附带一个__main__.Objobject的变量,相当于所有self的成员变量,其实也是局部变量的一部分。而如果使用co_varnames的方法,那么得到的就是所有局部变量的名称,我们也可以在例子中额外定义一个self的成员变量:
x=0
classObj:
def__init__(self,y):
self.p=5
self.func(y)
deffunc(self,y,z=1):
m=2
print(locals())
print(vars())
print(__import__('sys')._getframe(0).f_code.co_varnames)
if__name__=='__main__':
Obj(2)
#{'self':__main__.Objobjectat0x7fe9aac0ce50,'y':2,'z':1,'m':2}
#{'self':__main__.Objobjectat0x7fe9aac0ce50,'y':2,'z':1,'m':2}
#('self','y','z','m')
可以发现,所有的成员变量都被放在了self中。并且需要注意的是,全局变量x自始至终都没有在局部变量中出现。那么既然我们可以通过这种方式分离出局部变量,或者是局部变量的名称,那我们如何去调整或者修改这些局部变量呢?首先我们需要知道,locals()方法返回的变量是一个copy,也就是说即使修改了locals方法返回的结果,也不能真正的改变局部变量本身的值,这样描述可能有点抽象,我们直接看下这个案例:
x=0
classObj:
def__init__(self,y):
self.func(y)
deffunc(self,y,z=1):
m=2
vars()['z']=2
locals()['n']=3
print(locals())
print(z)
if__name__=='__main__':
Obj(2)
在这个案例中分别通过vars方法和locals方法去修改局部变量的值,最终的输出结果如下:
{self:__main__.Objobjectat0x7f74d9470e50,y:2,z:1,m:2,n:3}
1
首先要解释一下为什么这个案例中没有打印n这个变量,前面提到vars和locals的返回值都是真实变量的一个copy,因此我们不管是修改也好,新增也好,内容不会同步到变量空间中去,也就是说,此时的局部变量n还是处于一个没有定义的状态,只是在locals或者vars的字典中存在,此时打印只会报错NameError。而z的最终打印输出是1,这表明z的值确实没有受到对vars的变量修改的影响。那到底有没有办法可以通过字符串去修改局部变量呢(不同步到全局变量)?答案是有的,但是这个方案非常的hacky,请看如下示例:
importctypes
x=0
classObj:
def__init__(self,y):
self.func(y)
deffunc(self,y,z=1):
m=2
__import__('sys')._getframe(0).f_locals.update({
'z':2,'n':3
ctypes.pythonapi.PyFrame_LocalsToFast(
ctypes.py_object(__import__('sys')._getframe(0)),ctypes.c_int(0))
print(locals())
print(z)
if__name__=='__main__':
Obj(2)
这个案例是使用了Cython的方案直接去修改了数据帧的内容,而这里所使用的f_locals其实本质上就是locals。经过一番运行,输出结果如下:
{self:__main__.Objobjectat0x7fea2e2
a1e80,y:2,z:2,m:2,n:3}
2
此时局部变量z是被成功修改了的,但是在前面提到的,即使我们通过这种方法修改了局部变量的值,但是依然不能通过这个方案去创建一个新的局部变量,此时去执行print(n)的话,依然会有报错提示。
读取和修改全局变量
相比于修改局部变量,其实查看修改全局变量要显的更加容易。首先我们用一个示例演示一下如何查看所有的全局变量:
x=0
classObj:
def__init__(self,y):
self.func(y)
deffunc(self,y,z=1):
m=2
print(globals())
if__name__=='__main__':
Obj(2)
获取局部变量的方式有很多,但是获取全局变量一般就是globals或者等价的f_globals。上述代码执行输出如下:
{__name__:__main__,__doc__:None,__package__:None,
__loader__:_frozen_importlib_external.SourceFileLoaderobjectat0x7f202632ac40,
__spec__:None,__annotations__:{},__builtins__:modulebuiltins(built-in),
__file__:xxx.py,__cached__:None,x:0,Obj:class__main__.Obj}
用这种方法我们发现了全局变量x,而在同一个函数内的几个局部变量,就没有显示在globals的key中。而不同于locals变量的是,globals函数返回的是一个真实的数据,是可以直接修改,并且在全局生效的。比如我们在函数内定义或者修改全局变量:
x=0
classObj:
def__init__(self,y):
self.func(y)
deffunc(self,y,z=1):
globalm
m=2
globals()['x']=3
if__name__=='__main__':
Obj(2)
print(globals()['x'])
print(globals()['m'])
#2
在这个例子中我们就可以发现,不仅仅是修改的x值生效了,新建的m也同步到了全局变量中,这样就可以比较容易的划分全局变量和局部变量再进行统一赋值或者修改。
读取和修改成员变量
在python中每一个定义的object都有一个隐藏属性__dict__,这是一个字典,其中包含了所有的成员变量名和成员变量值。在前一篇博客中,我们就介绍了通过__dict__去给类中的成员变量进行赋值,非常的方便。我们可以通过一个示例来看看__dict__中所包含的内容:
x=0
classObj:
def__init__(self,y):
self.m=2
self.func(y)
deffunc(self,y,z=1):
print(self.__dict__)
if__name__=='__main__':
Obj(2)
#{'m':2}
从输出结果中我们就可以看到,__dict__输出的内容非常的纯净,就是所有的成员变量名和变量值。而成员变量虽然是一个对象的属性,但是其操作方式跟全局变量globals是非常接近的,不像locals一样只读,具体示例如下:
x=0
classObj:
def__init__(self,y):
self.m=2
self.func(y)
deffunc(self,y,z=1):
self.m=5
self.__dict__['n']=6
print(self.__dict__)
print(self.m,self.n)
if__name__=='__main__':
Obj(2)
#{'m':5,'n':6}
#6
在这个案例中,我们修改了成员变量的值,也使用__dict__新建了一个成员变量的值,可以看到最终都有同步到变量空间中,这样就完成了成员变量的修改。
总结概要
Python本身是一门比较灵活便捷的编程语言,但是便捷往往有
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年三明市农业农村局直属事业单位选聘真题
- 2024年青海省邮政管理局下属事业单位真题
- 企业数字化转型的战略价值试题及答案
- 2024年西安市曲江第六小学招聘笔试真题
- 2024年四川省骨科医院招聘笔试真题
- 2024年贵州省能源局下属事业单位真题
- 2024年贵阳市观山湖区第十一小学招聘教师真题
- 2024年民生银行成都研发中心招聘笔试真题
- VB考试模拟冲刺试题及答案
- 网络管理员考试问题汇聚试题及答案
- 计算机的基本工作原理初中七年级上册信息技术课件
- 肠瘘 课件教学课件
- 加油站防雷制度档案
- 2024年四川省巴中市中考文科综合试卷(含答案解析)
- 欠款抵车的协议书范本
- 设备购买合同模板示例
- 基于JAVA的宠物管理系统实现毕业论文
- 2024年小区地下车位租赁合同
- 2022-2023学年上海市闵行区八年级(下)期末数学试卷
- 专题03 陕西省(A卷)-2022-2023年各地中考英语听力真题合集(含听力原文及MP3)
- 诺如病毒校园防控知识
评论
0/150
提交评论