Python中如何将字符串常量转换为变量?

如何动态生成变量名?

相信大多数同学在看到本文标题后内心是疑惑的,到底什么样的场景下会遇到这种需求呢?接下来我们通过技术讨论群抛出的问题以及一系列答案做一个分析,并由此引申到更进一步的学习话题,希望对各位同学有所帮助。

首先,M同学的问题如下:

打扰一下大家,请教个问题,已知list = ['A', 'B', 'C', 'D'],  
如何才能得到以list中元素命名的新列表A = [], B = [], C = [], D = []呢?  

简单理解,这个问题的意思是,将字符串内容作为其它对象的变量名
list 中的元素是字符串,此处的 ‘A’-‘D’ 是常量 ,而在要求的结果中,A-D 是变量
如果强行直接将常量当做变量使用,它会报错:
111
报错中的 literal 指的是 字面量 ,这是计算机科学中常见的一个概念,用于表达源代码中的固定值。 例如,整数、浮点数、字符串等基本类型,就是字面量。

字面量指的就是一个量本身,可以理解为一种原子性的实体,当然不能再被赋值了。
所以,取出的字符串内容,并不能直接用作变量名,需要另想办法。

有初学者可能会想,list[0] = [] 行不行?当然不行,因为没有出现 A 。那 A = list[0] ,接着 A = [] 呢?那也不行,因为这里的 A 是你凭空定义出来的,而不是从已有条件中生成的。

当时,群里只有两三个同学参与了讨论,我们没想到解决办法。但是,我觉得这个题目很有意思,值得玩味。

因为,如果能解决这个问题,那就意味着可以不作预先定义,而是动态地生成变量名,这不仅能减少给变量取名的麻烦,还实现了自动编码!

可以设想一下未来,人工智能在编写代码的时候,如果能根据已知条件,动态生成变量名,那编写代码的过程不就顺利多了么?(据说,现在已经有人工智能可以编写代码了,不知它在取变量名时,是用的什么方法?)

车到山前必有路

最近,学习群里蒙混进来了几个打广告的,为此,群主决定提高审核门槛,例如,用群里的问题来作个考核。

万万没想到的是,第一个被考核到的 Q 同学,几乎不假思索地就说出了一个解决上述问题的思路。而偏偏就是那么巧 ,几乎在同时,群内的 J 同学给出了另外一个解决方法(他没看到群内的讨论,而是看到了知识星球的记录,才知道这个问题的)。
也就是说,前一晚还以为无解的问题,在第二天竟得到了两种不同的解决方法!

那么,他们的答案是什么呢?
222
这个方法通过修改全局命名空间,巧妙地“定义”出了新的变量。globals() 方法取出来的是一个字典,字符串 ‘A’ 是其中一个键值(key),而这个键值恰恰是全局命名空间中的一个变量,这就实现了从常量到变量的转化。

在数据结构层面上,空列表 [] 作为一个值(value)跟它的字符串键值绑定在一起,而在运用层面上,它作为变量内容而跟变量名绑定在一起。

船到桥头自然直

新进群的 Q 同学,提供了一个不同的答案:
333
他的写法用到了 Python 3.6 才引入的 f-strings 特性,事实上,在较低版本中,也是可以实现的,只需要保证 exec() 方法接收的参数是包含了变量 i的字符串即可,例如这样写:
444
这几种写法的区别只是字符串拼接法的区别。
Q 同学这个答案的核心在于 exec() 方法,它是内置的,用途是执行储存在字符串或文件中的代码段

它的基础用法如下:
555
看完了 exec() 的用法,我们再回来看 Q 同学的答案。for 循环中取出来的 i是字符串,而拼接后的字符串经过 exec() 的处理,就获得了动态编写代码的效果。

也就是说,因为字符串常量的内容被当做有效代码而执行了,其中的 ‘A’-‘D’ 元素,就取得了新的身份,变成了最终的 A-D 变量名。

这个方法看起来很简单啊,可是 exec() 方法太生僻,直到 Q 同学提出,我们才醒悟过来。

注意:在 Python3 中,exec() 是个内置方法;  
而在 Python2 中,exec 是个语句(statement),  
另外有个 execfile() 方法,两者相合并,就成了 Python3 中的 exec() 方法。  
本文使用的是 Python3。  

总结

抽象一下最初的问题,它实际问的是“如何将字符串内容作为其它对象的变量名”,更进一步地讲是——“如何将常量转化为变量 ”。

使用直接进行赋值的静态方法,行不通。

两位同学提出的方法都是间接的动态方法:一个是动态地进行变量赋值,通过修改命名空间而植入变量;一个是动态地执行代码,可以说是通过“走后门”的方式,安插了变量

两种方法殊途同归,不管是白猫还是黑猫,它们都抓到了老鼠。

这两种方法已经给我们带来了很有价值的启发,同时,因为它们,群内小伙伴们更是发散地讨论一些相关联的话题,例如:S 同学提出了另一种修改命名空间中变量的写法、L 同学提到了 eval() 的意义、eval()exec() 的区别、我查到了为什么要慎用 eval()CH 同学提到了 eval() 的安全用法……

虽然,某些话题无法在群聊中充分展开,但是,这些话题知识的延展联系,大大地丰富了本文开头的问题,这一个微小的问题,牵连出来了两个大的知识体系。

原文出处

Python猫微信公众号:
Python进阶:如何将字符串常量转为变量?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值