总结
我有一个包含 10 多个字段 的数据类
。 print()
将它们隐藏在默认值墙中的有趣上下文 - 让我们通过避免不必要地重复这些来使它们更友好。
Python 中的数据类
Python 的 @dataclasses.dataclass()
( PEP 557 ) 提供自动打印表示 ( __repr__()
)。
假设这个例子,based on python.org's :
from dataclasses import dataclass
@dataclass
class InventoryItem:
name: str
unit_price: float = 1.00
quantity_on_hand: int = 0
装饰器,通过@dataclass(repr=True)
(默认)将 print()
一个不错的输出:
InventoryItem(name='Apple', unit_price='1.00', quantity_on_hand=0)
我想要的:跳过打印默认值
repr
它打印所有 字段,包括您不想显示的隐含默认值。
print(InventoryItem("Apple"))
# Outputs: InventoryItem(name='Apple', unit_price='1.00', quantity_on_hand=0)
# I want: InventoryItem(name='Apple')
print(InventoryItem("Apple", unit_price="1.05"))
# Outputs: InventoryItem(name='Apple', unit_price='1.05', quantity_on_hand=0)
# I want: InventoryItem(name='Apple', unit_price='1.05')
print(InventoryItem("Apple", quantity_on_hand=3))
# Outputs: InventoryItem(name='Apple', unit_price=1.00, quantity_on_hand=3)
# I want: InventoryItem(name='Apple', quantity_on_hand=3)
print(InventoryItem("Apple", unit_price='2.10', quantity_on_hand=3))
# Output is fine (everything's custom):
# InventoryItem(name='Apple', unit_price=2.10, quantity_on_hand=3)
讨论
在内部,这是从 python 3.10.4
开始的 dataclass
repr
生成器的机制:cls.__repr__
=
_repr_fn(flds, globals))
-> _recursive_repr(fn)
可能是 @dataclass(repr=False)
被关闭并添加 def __repr__(self):
的情况。
如果是这样,那会是什么样子?我们不想包含可选的默认值。
上下文
重复一下,在实践中,我的数据类
有10+个字段。
我通过运行代码和 repl 来print()
ing 实例,并且 @pytest.mark.parametrize
运行时 pytest使用 -vvv
。
大数据类的非默认值(有时是输入)是不可能看到的,因为它们被埋在默认字段中,更糟糕的是,每一个都非常大且令人分心:掩盖了打印出来的其他有值(value)的东西。
相关问题
截至今天,dataclass
问题还不多(这可能会改变):
- Extend dataclass' __repr__ programmatically : 这是试图限制 repr。它应该显示 less 字段,除非它们被明确覆盖。
- Python dataclass generate hash and exclude unsafe fields : 这是为了散列,与默认值无关。
最佳答案
你可以这样做:
import dataclasses
from dataclasses import dataclass
from operator import attrgetter
@dataclass(repr=False)
class InventoryItem:
name: str
unit_price: float = 1.00
quantity_on_hand: int = 0
def __repr__(self):
nodef_f_vals = (
(f.name, attrgetter(f.name)(self))
for f in dataclasses.fields(self)
if attrgetter(f.name)(self) != f.default
)
nodef_f_repr = ", ".join(f"{name}={value}" for name, value in nodef_f_vals)
return f"{self.__class__.__name__}({nodef_f_repr})"
# Prints: InventoryItem(name=Apple)
print(InventoryItem("Apple"))
# Prints: InventoryItem(name=Apple,unit_price=1.05)
print(InventoryItem("Apple", unit_price="1.05"))
# Prints: InventoryItem(name=Apple,unit_price=2.10,quantity_on_hand=3)
print(InventoryItem("Apple", unit_price='2.10', quantity_on_hand=3))
关于python - 从 python `dataclass` `__repr__` 中排除默认字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72161257/