python变量名称的规定_Python 趣闻:如何获得变量的名字?

获取变量名

今天我们探讨Python中一个看似很简单,实则并不容易的问题。这个问题是:如何获得变量的名字?

举例说明,给定一个变量var,给它赋值字符串"foo"。即

In [1]: var = "foo"

现在我们需要得到变量var的名字,即"var"。

尝试下面两种方法,我们得到的都是变量的值"foo",而不是变量的名字"var"。

In [2]: print var

foo

In [3]: print "%s" % var

foo

怎么办呢?我们接着探索变量var的全部属性和方法:

In [4]: print dir(var)

['__add__', '__class__', '__contains__', ..., 'capitalize', 'center', ...]

经过尝试后发现,在var的71个(这个数字通过print len(dir(var))得到)属性和方法中,没有一个能够让我们得到var的名字。

由此可见,得到变量值(value)容易,得到变量名(name)看起来十分困难。

两个示例

在进一步探索其他方案之前,我们先看下"获取变量名"在Python编程中到底有没有实际意义。这里,举两个小例子,说明"获得变量名"的好处。

示例1

第一个例子是关于异常处理的。如果能够得到变量名,那么Python异常的错误消息(Error Message)将变得更加有意义。例如:

1 first_num, second_num = 1, 2

2 if first_num != second_num:

----> 3 raise RuntimeError("%s is not equal to %s" % (first_num, second_num))

RuntimeError: 1 is not equal to 2

这里错误消息RuntimeError: 1 is not equal to 2的可读性是比较差的,1和2分别是什么?我们需要结合源码才能明白。假如能够在Error Message中输出1和2各自的变量名first_num和second_num,无疑是一件好事情。

示例2

第二个例子是基于一组变量创建字典。已知若干变量,name, address, age, gender,我们希望基于它们创建一个字典person。一般可以这样实现:

person = {}

person["name"] = name

person["address"] = address

person["age"] = age

person["gender"] = gender

虽然这种实现完全可行,但是对于像我这样有"洁癖"的Python爱好者来说,有两点觉得不舒服。一是变量的名字出现了重复;二是赋值语句(不管是=赋值还是:赋值)出现了重复。当变量数量越多时,重复情况就越多。

如果能够使用类似下面这种循环来实现,代码就能更加简洁:

for i in [name, address, age, gender]:

person[i] = i # 由于i是变量值,因此不可行

以上两个示例说明获得变量名对于Python编程是有好处的。

一种间接方案

然而,在前文我们也看到了,得到Python变量名是困难的。那么,为什么无法直接得到Python变量名呢?查阅相关资料后发现,在Python中,变量名字是对象(object)的单向(而不是双向)引用。也就是说,根据变量名,能够直接得到它所指向的对象;反之,根据对象,是无法得到指向它的变量名的。

之所以有这么一个规定,是基于成本考虑的。在程序中,往往存在大量的变量(整型,字符串,列表,字典,布尔...)。如果每一个变量都需要有一个包含指向它的变量名的列表,那么这些列表的创建和维护的成本(实现成本,执行成本...)将变得难以承受。

既然直接方法不可行,那么有没有间接的方法呢?Python的inspect模块提供了一种间接方案。以示例2为例,基于inspect的For循环实现为:

import inspect

def retrieve_name(var):

callers_local_vars = inspect.currentframe().f_back.f_locals.items()

return [var_name for var_name, var_val in callers_local_vars if var_val is var]

name, address, age, gender = "bob", "hangzhou", 21, "man"

person = {}

for i in [name, address, age, gender]:

person[retrieve_name(i)[0]] = i

print person

执行脚本,结果符合预期:

root@hzettv53:~# python test.py

{'gender': 'man', 'age': 21, 'name': 'bob', 'address': 'hangzhou'}

这种方案的基本思路是:通过inspect模块的currentframe()方法得到一个包含调用者的所有局部变量的名字和值的列表,然后从列表中搜索变量值与目标值相同的元素,并返回该元素对应的变量名。

虽然这种方案在一些情况下能够工作,但是其弊端是显而易见的:1) 实现的复杂度较高 2) 如果存在多个变量值相同的情况,那么retrieve_name()函数将返回多个变量名,从而无法得到精确结果。基于这两点因素,这个方法中并没有多大的实际应用意义。

总结

综上所述,我们可以看到,Python编程中并不存在一种高效和可靠的方法去获得变量名。所幸的是,尽管获得变量名在某些场景下有好处,但是这种好处往往并不显著,并且一般都存在替代方案。因此,尽管Python无法支持获得变量名这一需求,但是日常的Python开发工作并不会因此受到多大影响。

最后,欢迎关注我的个人微信公众号《测试不将就》,我们一起探讨高质量软件养成之道。

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

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

相关文章

举例子说明什么是迭代什么是递归【转载】

举个例子bai&#xff1a;我想求1234..100的值。 迭代的做法&#xff1a;从1到100&#xff0c;顺着往下累加。123,336,6410,10515…… 程序表示&#xff0c; int i1,sum0; while(i<100){ sum sum i; } 递归的做法&#xff1a;我要求1到100的累加值&#xff0c;如果我已经得到…

Linux的实际操作:文件目录类的实用指令(touch cp)

1.touch 空文件 在当前路径下创建空文件 注意&#xff1a;mkdir是创建文件夹&#xff0c;touch是创建文件 那么有同学要问了&#xff0c;这个和上一章讲的vim创建一个文件有什么区别&#xff1f; 区别&#xff1a;vim创建完直接打开文件&#xff0c;touch不会直接…

loss下降auc下降_梯度下降算法 线性回归拟合(附Python/Matlab/Julia源代码)

梯度下降梯度下降法的原理梯度下降法(gradient descent)是一种常用的一阶(first-order)优化方法&#xff0c;是求解无约束优化问题最简单、最经典的方法之一。梯度下降最典型的例子就是从山上往下走&#xff0c;每次都寻找当前位置最陡峭的方向小碎步往下走&#xff0c;最终就会…

台式电脑耳机插孔在哪_吉林戴尔电脑音箱维修app,查看详情_曹操闪修

首页 > 新闻列表 > 正文发布时间&#xff1a;2020-10-24 01:14:13 浏览&#xff1a; 14导读&#xff1a;吉林戴尔电脑音箱维修app, 这样的问题一般只有三种解决方法&#xff0c;一种就是重新新冲突的驱动。第二种方法就是在中改变各自的中断&#xff0c;消除冲突。第三种…

Linux的实际操作:文件目录类的实用指令(rm mv)

其实rm和我们上几节学到的rmdir有点类似 &#xff0c;区别在哪里呢&#xff1f;rm是可以删除文件或者文件夹&#xff0c;rmdir是删除文件夹&#xff0c;而且如果是一个非空文件夹&#xff0c;是不能通过rmdir删除的&#xff0c;需要用rm -rf 去强制递归删除&#xff08;不懂的话…

无法将该对象添加到ldap服务器_LDAP 基础知识

LDAP 基础知识目录简介协议概览目录结构架构&#xff08;Schema&#xff09;对象类&#xff08;objectClass&#xff09;属性&#xff08;Attribute&#xff09;条目&#xff08;Entry&#xff09;LDAP 中的数据常用命令启动和关闭: start-ds / stop-ds检查 LDAP 服务器状态: s…

windows7系统损坏修复_【软件资讯】还在用win7?微软Windows 7系统正式停止技术支持...

本文转自IT之家&#xff0c;作者玄隐。早在2015年1月&#xff0c;微软结束了对Windows 7的主流支持&#xff0c;该公司停止向旧操作系统添加新功能。微软将Windows 7从主流支持转移到扩展支持。2020年1月14日&#xff0c;今天迎来了Windows 7的停止技术支持&#xff0c;微软将把…

Linux的实际操作:文件目录类的实用指令(cat more less)

1.cat 要查看的文件 &#xff08;是以只读的方式打开,区别于vim可以查看文件并且编辑&#xff09; cat -n 要查看的文件 &#xff08;只读&#xff0c;且提供行号&#xff09; cat -n 要查看的文件 | more &#xff08;这个操…

python中pickle模块_Python pickle模块的用法

串行化主要用于网络传输或者持久化。我们知道&#xff0c;网络上的数据都是字节流&#xff0c;如果希望将某个对象传送给远端的机器&#xff0c;首先就必须将其转换成字节流&#xff0c;然后才可以在网络上传输。文件也是字节流&#xff0c;如果希望将某个对象保存到文件中&…

电子测量与仪器第四版pdf_准确选择表面粗糙度仪的测量参数应该从哪些地方着手好【电子仪器吧】...

表面粗糙度仪的参数怎么选择&#xff1f;首先要先满足运用功能要求&#xff0c;其次再兼顾经济性能。即&#xff0c;在满足运用要求的前题下&#xff0c;尽可能下降外表粗糙度要求&#xff0c;放大表面粗糙度允许值。对多数外表面来说&#xff0c;给出高度特色评定参数即可反映…

Linux的实际操作:文件目录类的实用指令(重定向“>“和追加“>>“)

1. > 表示重定向 &#xff08;重定向什么意思呢&#xff1f;就是把一个文件的内容&#xff0c;保存到指定的位置&#xff09; > 是定向输出到文件&#xff0c;如果文件不存在&#xff0c;就创建文件&#xff1b;如果文件存在&#xff0c;就将其清空&#…

wrapper怎么用_用责任链模式设计拦截器

我在 Redant(https://github.com/all4you/redant) 中通过继承 ChannelHandler 实现了拦截器的功能&#xff0c;并且 pipeline 就是一种责任链模式的应用。但是我后面对原本的拦截器进行了重新设计&#xff0c;为什么这样做呢&#xff0c;因为原本的方式是在 ChannelHandler 的基…

VS2019 配色_这个双11,凯里-欧文陪你过!欧文6正式发布,城市版配色真的香

北京时间11月5日&#xff0c;在篮网主场对阵鹈鹕的比赛中&#xff0c;欧文一上场就让教主眼前一亮&#xff0c;这鞋骚的有点过分啊。欧文6代已经于北京时间11月5日正式发布&#xff0c;虽然首发配色毫无惊喜&#xff0c;毕竟早在休赛期就已经被曝得连底裤都不剩了&#xff0c;但…

Linux的实际操作:文件目录类的实用指令(echo head tail)

1.echo 输出内容到控制台 例子&#xff1a;实用echo指令输出环境变量&#xff0c;输出当前的环境变量路径 2.head 用于显示文件的开头部分内容&#xff0c;默认情况下head显示文件的前10行内容&#xff08;因为有些文件比较大&#xff0c;我们有时候不全去看&#xff09; 空格…

如何延长作用域链_通过实例理解javaScript中的this到底是什么和它的词法作用域...

最近&#xff0c;听到李笑来说&#xff0c;讲解编程的过程中&#xff0c;举例子很重要。而且&#xff0c;我最近看的各种javaScript工具书中的例子&#xff0c;也都有点复杂。所以啊&#xff0c;我试着举一些简单又直观的例子&#xff0c;与各位苦学javaScript的同学&#xff0…

word2vector数据集样式_这样做数据可视化驾驶舱,高端大气,一目了然,领导不点赞都难...

2020年了&#xff0c;数据可视化已经不是个新鲜词了&#xff0c;把数据以可视化图表的形式展示并没有多神奇&#xff0c;用Excel等传统的办公工具就可以轻松实现。以前传统数据分析报告就是ppt里贴图表&#xff0c;再配上分析结论&#xff0c;这种形式的数据呈现是静态的&#…

Linux的实际操作:文件目录类的实用指令(ln history)

1.ln 软连接也叫做符号链接&#xff0c;类似于windows的快捷方式&#xff0c;主要是存放了链接其它文件的路径 ln -s 原文件或者目录 软链接名 &#xff08;功能&#xff1a;给原文件创建一个软链接&#xff09; 案例&#xff1a;将/roo…

mysql 删除重复数据_日常答疑|MySQL删除重复数据踩过得坑

问题群友提问&#xff1a;MySQL这样删除重复数据为啥不成功呢&#xff1f;严小样儿&#xff1a;安排&#xff01;咋一看&#xff0c;大家都说where子句里面应该使用极值函数&#xff0c;加个max就对了&#xff0c;这么简单&#xff01;# 大家想象中这样写是对的&#xff0c;其实…

搜狗手机浏览器_搜狗推广开户费多少钱?【搜狗开户代理商】

搜狗开户流程提供落地页审核提供服务器ip 安排解析账户预存款4000币上传关键词及素材开启广告上线福如海广告&#xff0c;搜狗开户代理商全国行业开户&#xff0c;有无资质均可手机&#xff1a;18705657032【同微信】搜狗广告详细介绍搜狗广告展现形式PC端-搜狗搜索推广当网民在…

Linux命令终端提示符显示-bash-4.2#解决方法【转载】

昨天在配置linux&#xff0c;突然发现root登录的CRT的终端提示符显示的是-bash-4.2# 而不是root主机名 路径的显示方式。搞了半天也不知道为什么出现这种情况。今天终于搞定这个问题&#xff0c; 原因是root在/root下面的几个配置文件丢失&#xff0c;丢失文件如下&#xff1a…