nco*_*lan 13 python python-3.x
在最近写一堂课时,我最初提出了一个__repr__方法,大致如下:
return "{}({!r}, {!r}, {!r})".format(
                self.__class__.__name__,
                self.arg1,
                self.arg2,
                self.arg3)
Run Code Online (Sandbox Code Playgroud)
重复那样的'{!r}'代码片段感觉不对,如果我再向这个类添加更多参数,那么维护是很乏味的.然而,对我来说,更强大的替代方案也不会赢得任何优雅的奖品.
以编程方式构建格式字符串:
fmt = "{}(%s)" % ", ".join(["{!r}"]*3)
return fmt.format(self.__class__.__name__,
                  self.arg1,
                  self.arg2,
                  self.arg3)
Run Code Online (Sandbox Code Playgroud)
使用str.join以下命令单独格式化参数:
args = ", ".join(map(repr, [self.arg1, self.arg2, self.arg3]))
return "{}({})".format(self.__class__.__name__, args)
Run Code Online (Sandbox Code Playgroud)
我目前使用最后一个示例实现了该类,但我对替代方法的建议感兴趣(因为我对上述任何选项都不是特别满意).
更新: 受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'
Run Code Online (Sandbox Code Playgroud)
Update2: 我最后添加了第二个实用函数,几乎与agf的答案中的函数相同:
def call_repr(name, *args):
    return "{}({})".format(name, format_iter(args))
Run Code Online (Sandbox Code Playgroud)
所以最初的违规__repr__功能现在看起来像:
def __repr__(self):
    return call_repr(self.__class__.__name__,
                     self.arg1,
                     self.arg2)
Run Code Online (Sandbox Code Playgroud)
(是的,今天早些时候,其中一个原始构造函数的论点就消失了.)
我倾向于,如果你不喜欢这些代码,请将其隐藏在一个函数中:
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)
Run Code Online (Sandbox Code Playgroud)
        如果这是一个你要重复的模式,我可能会使用:
# 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)
Run Code Online (Sandbox Code Playgroud)
要么
# 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)
Run Code Online (Sandbox Code Playgroud)