Vin*_* W. 2 python python-attrs python-dataclasses
我刚开始使用attrsPython 模块,它非常漂亮(或者类似地,我们可以使用 Python 3.7 DataClasses)。我有一个常见的使用模式是让类成为参数值的容器。我喜欢分配参数时的标签,以及更清晰的属性样式引用值,但我也喜欢在将值存储在有序 dict 之类的东西中时有几个很好的功能:
*像 atuple或 a一样解包list以输入函数参数** 当需要或需要传递关键字时解压缩。我可以通过在类中添加三个方法来实现这一切
@attr.s
class DataParameters:
A: float = attr.ib()
alpha: float = attr.ib()
c: float = attr.ib()
k: float = attr.ib()
M_s: float = attr.ib()
def keys(self):
return 'A', 'alpha', 'c', 'k', 'M_s'
def __getitem__(self, key):
return getattr(self, key)
def __iter__(self):
return (getattr(self, x) for x in self.keys())
Run Code Online (Sandbox Code Playgroud)
然后我可以使用这样的类:
params = DataParameters(1, 2, 3, 4, 5)
result1 = function1(100, 200, *params, 300)
result2 = function2(x=1, y=2, **params)
Run Code Online (Sandbox Code Playgroud)
这里的动机是数据类提供方便和清晰。然而,我不知道我正在编写的模块要求使用数据类是有原因的。希望函数调用应该接受简单的参数,而不是复杂的数据类。
上面的代码很好,但我想知道我是否遗漏了一些可以让我跳过编写函数的东西,因为模式非常清晰。属性按照我希望它们解包的顺序添加,并且可以根据关键字参数的属性名称作为键值对读取。
也许这是这样的:
@addtupleanddictunpacking
@attr.s
class DataParameters:
A: float = attr.ib()
alpha: float = attr.ib()
c: float = attr.ib()
k: float = attr.ib()
M_s: float = attr.ib()
Run Code Online (Sandbox Code Playgroud)
但我不确定是否有什么东西attrs可以做到这一点,我还没有找到。另外,我不确定如何在添加属性时保持它们的顺序,并将其转换为 keys 方法。
它不直接集成到类,但在asdict和astuple辅助功能的目的是进行这种转换。
params = DataParameters(1, 2, 3, 4, 5)
result1 = function1(100, 200, *attr.astuple(params), 300)
result2 = function2(x=1, y=2, **attr.asdict(params))
Run Code Online (Sandbox Code Playgroud)
它们没有集成到类本身中,因为这会使类在任何地方都表现为序列或映射,这会导致在需要TypeError/时出现无声的错误行为AttributeError。性能方面,这应该没问题;解包无论如何都会转换为tuple/ dict(它不能直接传递不是 atuple或dictin 的东西,因为 C API 希望能够在其参数上使用特定于类型的 API)。
如果您真的希望该类充当序列或映射,则基本上必须执行已完成的操作,尽管您可以使用辅助函数来减少自定义代码和重复的变量名称,例如:
@classmethod
def keys(cls):
return attr.fields_dict(cls).keys()
def __getitem__(self, key):
return getattr(self, key)
def __iter__(self):
return iter(attr.astuple(self, recurse=False))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2330 次 |
| 最近记录: |