Python 无法使用分部as\uu str__

Python 无法使用分部as\uu str__,python,namedtuple,Python,Namedtuple,我在尝试为一个程序编写一个漂亮的打印过程时遇到了这个问题,在这个程序中,我使用了几个包含浮点对的命名元组 from collections import namedtuple Position = namedtuple('Position', 'x y') Vector = namedtuple('Vector', 'x y') Size = namedtuple('Size', 'width height') 我想在打印时格式化浮点数,因为: import math print(Positi

我在尝试为一个程序编写一个漂亮的打印过程时遇到了这个问题,在这个程序中,我使用了几个包含浮点对的命名元组

from collections import namedtuple
Position = namedtuple('Position', 'x y')
Vector = namedtuple('Vector', 'x y')
Size = namedtuple('Size', 'width height')
我想在打印时格式化浮点数,因为:

import math
print(Position(math.pi, math.pi), Vector(math.pi, math.pi), Size(math.pi, math.pi))
太长了:

Position(x=3.141592653589793, y=3.141592653589793) Vector(x=3.141592653589793, y=3.141592653589793) Size(width=3.141592653589793, height=3.141592653589793)
因此,我创建了一个函数来打印命名元组:

def pretty_float_pair(name, labels, obj):
    """
    If labels = ('a', 'b') and object = (1.2345, 1.2345) returns:
        'name(a=1.23, b=1.23)'
    """
    return '{}({}={:.2f}, {}={:.2f})'.format(name, labels[0], obj[0], labels[1], obj[1])
每个类型的名称和标签都应该是固定的,只有obj参数不同,所以我想我可以使用functools

from functools import partial
Position.__str__ = partial(pretty_float_pair, 'Position', ('x', 'y'))
Vector.__str__ = partial(pretty_float_pair, 'Vector', ('x', 'y'))
Size.__str__ = partial(pretty_float_pair, 'Size', ('width', 'height'))
print(Position(math.pi, math.pi), Vector(math.pi, math.pi), Size(math.pi, math.pi))
但这会抛出一个类型错误:pretty\u float\u pair缺少1个必需的位置参数:“obj”

令人惊讶的是,如果我使用lambda来创建它可以工作的函数

Position.__str__ = lambda x: pretty_float_pair('Position', ('x', 'y'), x)
Vector.__str__ = lambda x: pretty_float_pair('Vector', ('x', 'y'), x)
Size.__str__ = lambda x: pretty_float_pair('Size', ('width', 'height'), x)
print(Position(math.pi, math.pi), Vector(math.pi, math.pi), Size(math.pi, math.pi))
打印我想要的:

Position(x=3.14, y=3.14) Vector(x=3.14, y=3.14) Size(width=3.14, height=3.14)

我试图理解部分版本不起作用的原因。

函数通过以下方式获得其隐式自参数:lookup x.f构造并返回一个记住x的方法对象,以便将其提供给f。功能工具。部分。。。不会返回描述符,因此不会得到特殊处理。它实际上是一个类,因此它返回自身的一个实例。

返回一个非描述符可调用的,大致相当于一个未绑定的方法。这意味着它没有被传递一个self参数,这与您看到的错误一致

由于lambda的行为类似于使用def定义的常规函数,因此它实际上是一个描述符。lambda的_get_uuu方法返回一个绑定版本,该版本在实例中作为x传递

若要获取行为更像方法的分部函数,请改用。您必须将obj移动到参数列表的开头,以便在绑定方法时它可以接收self

以下是您的示例:

from functools import partialmethod def pretty_float_pair(obj, name, labels): """ If labels = ('a', 'b') and object = (1.2345, 1.2345), returns: name(a=1.23, b=1.23) """ return '{}({}={:.2f}, {}={:.2f})'.format(name, labels[0], obj[0], labels[1], obj[1]) Position.__str__ = partialmethod(pretty_float_pair, 'Position', ('x', 'y')) Vector.__str__ = partialmethod(pretty_float_pair, 'Vector', ('x', 'y')) Size.__str__ = partialmethod(pretty_float_pair, 'Size', ('width', 'height')) print(Position(math.pi, math.pi), Vector(math.pi, math.pi), Size(math.pi, math.pi))
我不会因为这一点而否决投票,但你需要有一个解决方案来得到答案。物理学家:这个问题没有任何疑问,但我写这篇文章是为了解决这个问题,我试图理解为什么部分版本不起作用。你是完全正确的+1.OP在他们的问题中有着如此强烈的含义,我太累了,我读到了一些与我脑海中实际问题截然不同的东西。谢谢你的捕获。谢谢你的有用文档。你的函数没有正确缩进。请修理。您可以使用我的答案作为参考。即使您的问题已结束,您也应该从发布的答案中选择一个对您有帮助的答案。