namedtuple - 更新 NamedTuple 中的字段(通过键入)
问题描述
我正在寻找一种更 Pythonic 的方式来更新 NamedTuple 中的字段(通过键入)。我在运行时从文本文件中获取字段名称和值,因此使用了 exec,但我相信,一定有更好的方法:
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
from typing import NamedTuple
class Template (NamedTuple):
number : int = 0
name : str = "^NAME^"
oneInstance = Template()
print(oneInstance)
# If I know the variable name during development, I can do this:
oneInstance = oneInstance._replace(number = 77)
# I get this from a file during runtime:
para = {'name' : 'Jones'}
mykey = 'name'
# Therefore, I used exec:
ExpToEval = "oneInstance = oneInstance._replace(" + mykey + " = para[mykey])"
exec(ExpToEval) # How can I do this in a more pythonic (and secure) way?
print(oneInstance)
我想,从 3.7 开始,我可以用数据类解决这个问题,但我需要 3.6
解决方案
在 namedtuples 上使用_replace
无论如何都不能成为“pythonic”。命名元组是不可变的。如果您使用命名元组,其他开发人员会认为您不打算更改您的数据。
pythonic 方法确实是dataclass。您也可以在Python3.6中使用数据类。只需使用来自 PyPi 的数据类 backport。
然后整个事情变得非常可读,您可以轻松地使用getattr
和setattr
按名称寻址属性:
from dataclasses import dataclass
@dataclass
class Template:
number: int = 0
name: str = "^Name^"
t = Template()
# use setattr and getattr to access a property by a runtime-defined name
setattr(t, "name", "foo")
print(getattr(t, "name"))
这将导致
foo
推荐阅读
- amazon-web-services - aws cloudformation - 在我的 vpc 中启动 ec2 实例
- reactjs - 如何使用borderRadius在本机反应中圆角?
- java - Spring Kafka:按顺序阅读两个不同的主题
- java - onTouch() 未触发
- java - Android:未找到 setTextTypeFace 字体资源
- python-3.x - 从 Azure Databricks 读取 Azure Datalake Gen2 映像
- php - Symfony 服务是如何默认私有的?
- json - 如何在嵌套的json中用jq查找和替换值
- .net - 当一个线程等待来自另一个线程的信号时,使用 Thread.Sleep 是否比 ManualResetEvent 使用更多的处理器?
- c - 将取自用户的大写字母放入数组中