Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将格式化的iterable作为较大的格式化字符串的一部分_Python_Python 3.x - Fatal编程技术网

Python 将格式化的iterable作为较大的格式化字符串的一部分

Python 将格式化的iterable作为较大的格式化字符串的一部分,python,python-3.x,Python,Python 3.x,在最近编写的一个类中,我最初包括了一个\uuu repr\uu方法,大致如下: return "{}({!r}, {!r}, {!r})".format( self.__class__.__name__, self.arg1, self.arg2, self.arg3) 像这样重复“{!r}”代码段感觉是错误的,如果我再向这个类添加任何参数,那么维护这个代码段将非常乏

在最近编写的一个类中,我最初包括了一个
\uuu repr\uu
方法,大致如下:

return "{}({!r}, {!r}, {!r})".format(
                self.__class__.__name__,
                self.arg1,
                self.arg2,
                self.arg3)
像这样重复“{!r}”代码段感觉是错误的,如果我再向这个类添加任何参数,那么维护这个代码段将非常乏味。然而,我想到的更健壮的替代品也不会赢得任何优雅的奖项

以编程方式生成格式字符串:

fmt = "{}(%s)" % ", ".join(["{!r}"]*3)
return fmt.format(self.__class__.__name__,
                  self.arg1,
                  self.arg2,
                  self.arg3)
使用
str.join
分别格式化参数:

args = ", ".join(map(repr, [self.arg1, self.arg2, self.arg3]))
return "{}({})".format(self.__class__.__name__, args)
我目前使用上一个示例实现了这个类,但我对其他方法的建议很感兴趣(因为我对上面的任何选项都不太满意)

更新: 受Ned答案的启发,我现在在助手模块中添加了以下实用功能:

def format_iter(iterable, fmt='{!r}', sep=', '):
    return sep.join(fmt.format(x) for x in iterable)

>>> format_iter(range(10))
'0, 1, 2, 3, 4, 5, 6, 7, 8, 9'
>>> format_iter(range(10), sep='|')
'0|1|2|3|4|5|6|7|8|9'
>>> format_iter(range(10), fmt='{:04b}', sep='|')
'0000|0001|0010|0011|0100|0101|0110|0111|1000|1001'
>>> format_iter(range(10), fmt='{0.real}+{0.imag}j')
'0+0j, 1+0j, 2+0j, 3+0j, 4+0j, 5+0j, 6+0j, 7+0j, 8+0j, 9+0j'
更新2: 我最后添加了第二个实用函数,与agf答案中的函数几乎相同:

def call_repr(name, *args):
    return "{}({})".format(name, format_iter(args))
因此,原来有问题的
\uuuu repr\uuuu
函数现在看起来像:

def __repr__(self):
    return call_repr(self.__class__.__name__,
                     self.arg1,
                     self.arg2)

(是的,今天早些时候,一个原始构造函数参数消失了。)

如果您不喜欢代码,我倾向于将其隐藏在函数中:

def repr_all(*args):
    return ", ".join(repr(a) for a in args)


def __repr__(self):
    args = repr_all(self.arg1, self.arg2, self.arg3)
    return "{}({})".format(self.__class__.__name__, args)

如果这是您要重复的模式,我可能会使用:

# This is a static method or module-level function
def argrepr(name, *args):
    return '{}({})'.format(name, ', '.join(repr(arg) for arg in args))

def __repr__(self):
    return argrepr(self.__name__, self.arg1, self.arg2, self.arg3)

我可以这样做:

def __repr__(self):
    return "{0}({1})".format(
        type(self).__name__,
        ", ".join(repr(arg) for arg in (self.arg1, self.arg2, self.arg3)))
或:


被接受,因为这是我最终所做的事情的直接灵感(见更新)好吧,这是一段时间内被接受的答案,直到我的解决方案演变成更像agf的建议:)事实证明,我最终这样做了,只是用一个
format\u iter(args)
调用代替了
str.join
def __repr__(self):
    return "{0}({1})".format(
        type(self).__name__,
        ", ".join(repr(arg) for arg in (self.arg1, self.arg2, self.arg3)))
_init_getter = operator.attrgetter('arg1', 'arg2', 'arg3')
def __repr__(self):
    return "{0}({1})".format(
        type(self).__name__,
        ", ".join(repr(arg) for arg in self._init_getter(self)))