从python`dataClass“ __repr__”中排除默认字段

发布于 2025-01-27 12:26:59 字数 4162 浏览 4 评论 0 原文

摘要

我有 dataclass 带有 10+字段 print()将它们埋在默认墙壁中的有趣上下文 - 让我们不必要地重复这些内容使它们变得更加友好。

python中的dataclasses

python's pep 557 )提供自动可打印表示( <

假设此示例,基于Python 。

from dataclasses import dataclass


@dataclass
class InventoryItem:
    name: str
    unit_price: float = 1.00
    quantity_on_hand: int = 0

​ - ,ret, - %3A%20if%20true%20(“ rel =“ noreferrer”> @dataclass(repl = true) (默认)Will print> print() 不错的输出:

InventoryItem(name='Apple', unit_price='1.00', quantity_on_hand=0)

我想要的:跳过打印默认值

包括您不想显示的隐含默认值。

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)

reprep 它打印 all

字段, 这是 dataclass的机械 repr - python 3.10.4 cls .__ spr.__ epr __ = “ noreferrer”> _repr_fn(flds,flds,Globals))> - &gt; _recursive_repr(fn)

可能是 @dataclass(repl = false)被关闭, def> def __repr __(self):被添加。

如果是这样,那会是什么样?我们不想包括可选默认值。

上下文

在实践中重复我的 dataclass 具有 10+字段

我是 print()通过运行代码和替代实例,以及 @pytest.mark.mark.parametrize 运行 pytest 带有 -vvv

大数据类别的非默认值(有时是输入)是无法看到的,因为它们被埋在默认字段中,更糟糕的是,每个默认情况下,每个默认情况都不比例地且令人分心的巨大:掩盖其他有价值的东西带来了印刷。

相关问题

截至今天, dataClass 问题还不多(可能会更改):

Summary

I have a dataclass with 10+ fields. print()ing them buries interesting context in a wall of defaults - let's make them friendlier by not needlessly repeating those.

Dataclasses in Python

Python's @dataclasses.dataclass() (PEP 557) provides automatic printable representations (__repr__()).

Assume this example, based on python.org's:

from dataclasses import dataclass


@dataclass
class InventoryItem:
    name: str
    unit_price: float = 1.00
    quantity_on_hand: int = 0

The decorator, through @dataclass(repr=True) (default) will print() a nice output:

InventoryItem(name='Apple', unit_price='1.00', quantity_on_hand=0)

What I want: Skip printing the defaults

repr It prints all the fields, including implied defaults you wouldn't want to show.

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)

Discussion

Internally, here's the machinery of dataclass repr-generator as of python 3.10.4: cls.__repr__=_repr_fn(flds, globals)) -> _recursive_repr(fn)

It may be the case that @dataclass(repr=False) be switched off and def __repr__(self): be added.

If so, what would that look like? We don't want to include the optional defaults.

Context

To repeat, in practice, my dataclass has 10+ fields.

I'm print()ing instances via running the code and repl, and @pytest.mark.parametrize when running pytest with -vvv.

Big dataclass' non-defaults (sometimes the inputs) are impossible to see as they're buried in the default fields and worse, each one is disproportionately and distractingly huge: obscuring other valuable stuff bring printed.

Related questions

As of today there aren't many dataclass questions yet (this may change):

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

時窥 2025-02-03 12:26:59

您可以这样做:

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))

You could do it like this:

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))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文