为什么string.Formatter.format没有“自我”参数?

时间:2018-12-26 18:26:07

标签: python string class self

在阅读python string模块的源代码时,我对类Formatter感到困惑。

Formatter类中的format方法(不是静态方法也不是类方法)没有将self作为输入参数def format(*args, **kwargs):,但是以某种方式直接在方法中使用它。 self, *args = args

请解释这种用法。

class Formatter:
    def format(*args, **kwargs):
        if not args:
            raise TypeError("descriptor 'format' of 'Formatter' object "
                            "needs an argument")
        self, *args = args  # allow the "self" keyword be passed
        try:
            format_string, *args = args # allow the "format_string" keyword be passed
        except ValueError:
            if 'format_string' in kwargs:
                ...
            else:
                ...
        return self.vformat(format_string, args, kwargs)

2 个答案:

答案 0 :(得分:5)

self被假定为arg中的第一个*args,并在以下行解压缩:

self, *args = args

在签名中声明不带self的实例方法在Python中是不常见的。

通过查看git history的方法签名行,我们可以看到原来存在self

已将其删除,因为如果格式字符串包含名为self的变量(例如'I am my{self}'),则它的存在会导致错误。从self拆包args的非正常模式被引入,以修复该错误。

错误报告和讨论是here

这是错误报告中的错误示例:

>>> string.Formatter().format('the self is {self}', self='bozo')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: format() got multiple values for argument 'self'

答案 1 :(得分:1)

我假设您熟悉参数中的*args语法。这只是未命名参数的任意列表。那你有

self, *args = args  # allow the "self" keyword be passed

该评论非常明确。您正在将args(这是一个列表)拆分为第一个元素(我们通常将其称为self,但它只是一个常规参数,始终是对象方法中的第一个参数),其余的则为。因此,我们读了self,一切都很好-不是立即,而是在函数中。

我在这里可以看到的唯一用例是

if not args:
        raise TypeError("descriptor 'format' of 'Formatter' object "
                        "needs an argument")

这意味着我们希望做类似的事情

Formatter.format(formatterObj,format_string,...)

很多(不确定为什么,有点像工厂吗?),所以在我的示例中忘记发送self-formatterObj的情况下,我们会收到冗长的错误。可能支持不具有Formatter方法但具有format方法的vformat类似对象。似乎不太可能。