最近在写一个类时,我最初包含了一个 __repr__
方法,如下所示:
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))
所以最初有问题的 __repr__
函数现在看起来像:
def __repr__(self):
return call_repr(self.__class__.__name__,
self.arg1,
self.arg2)
(是的,最初的构造函数参数之一在今天早些时候消失了。)
最佳答案
如果这是您要重复的模式,我可能会使用:
# 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)
或
# This is a static method or module-level function
def argrepr(*args):
return '(' + ', '.join(repr(arg) for arg in args) + ')'
def __repr__(self):
return repr(self.__name__) + argrepr(self.arg1, self.arg2, self.arg3)
关于python - 包括一个格式化的可迭代对象作为一个更大的格式化字符串的一部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7072938/