Python中如何通过存储实例名的变量获取对应namedtuple的属性与元素
问题根因
你现在代码跑出来不符合预期的核心原因很简单:
- 你写的
environment是个普通字符串,值就是"qa" - 你直接对这个字符串用
.name取属性、用下标取内容,操作的全是字符串本身,跟你之前定义的那个叫qa的凭证实例完全没关系 - Python不会自动把“存着变量名的字符串”和内存里真实的变量对象关联起来,不存在你写个字符串名,Python就自动帮你找到对应变量的这种隐式逻辑
正确实现方式
方案1:用字典统一存环境和凭证的对应关系(最推荐)
别把不同环境的凭证散在代码里当独立全局变量定义,专门建一个字典,把环境名当键,对应的凭证实例当值,取的时候直接用environment的值当字典的键就行。
示例代码:
from collections import namedtuple Credentials = namedtuple('Credentials',['name','password','ver']) environment = "qa" # 把所有环境的凭证统一存在这个字典里 env_cred_map = { "qa": Credentials('a', '1', ''), "qa_dev": Credentials('a', '2', 'd'), "live": Credentials('b', 'c', '') } # 直接根据environment的值取对应的凭证实例 current_cred = env_cred_map[environment] # 之后就可以正常用namedtuple的所有取值方法了 print(current_cred.name) # 这里会正常输出 a print(current_cred[1]) # 这里会正常输出 1
这种写法的好处:
- 所有配置集中放一起,逻辑一目了然,不会出现变量名撞车的问题
- 要加新的环境只要在字典里加一行键值对就行,改起来很方便
- 没有奇奇怪怪的隐式取变量逻辑,哪怕是刚接触代码的人看了也能懂
方案2:直接从全局变量区找独立定义的变量(不推荐新手用)
如果你就是不想用字典,非要把每个环境的凭证定义成独立的全局变量,那可以用Python内置的全局变量检索字典globals(),用存着变量名的字符串找到对应的真实对象。
示例代码:
from collections import namedtuple Credentials = namedtuple('Credentials',['name','password','ver']) environment = "qa" qa = Credentials('a','1','') qa_dev = Credentials('a','2','d') live = Credentials('b','c','') # 从全局变量表里,根据environment存的字符串找到对应的实例 current_cred = globals()[environment] print(current_cred.name) print(current_cred[1])
这种写法为啥不推荐:
- 如果传进来的环境名没对应定义过变量,会直接抛KeyError,错误提示啥上下文都没有,新手排查半天找不到原因
- 万一你不小心把environment的值改成了和其他无关全局变量重名的字符串,会取到完全不相关的对象,这种bug隐蔽性特别强,很难查到
- 代码可读性差,后面帮你维护代码的人根本想不到你这里是动态取变量,找半天找不到对应逻辑在哪
小提示
做这种“根据标识找对应配置”的需求,用字典映射是Python里最常用、最稳的写法,刚开始写代码的时候尽量别上来就用动态找全局变量的“高级”写法,很容易踩坑。
内容的提问来源于stack exchange,提问作者Epilogue
相关产品推荐
相关产品推荐

