2011-08-16 28 views
13

在最近寫入一個類,我最初包括沿着如下的__repr__方法的一部分:包括格式化可迭代作爲更大格式的字符串

return "{}({!r}, {!r}, {!r})".format(
       self.__class__.__name__, 
       self.arg1, 
       self.arg2, 
       self.arg3) 

重複該「{R!}」片斷等,感覺如果我曾經爲這堂課添加任何更多的論據,那麼將會是非常乏味的。然而,對我而言,更強大的替代品並不會贏得任何優雅的獎品。與str.join

fmt = "{}(%s)" % ", ".join(["{!r}"]*3) 
return fmt.format(self.__class__.__name__, 
        self.arg1, 
        self.arg2, 
        self.arg3) 

格式化參數分別:

構建格式字符串編程

args = ", ".join(map(repr, [self.arg1, self.arg2, self.arg3])) 
return "{}({})".format(self.__class__.__name__, args) 

我用最後的例子目前實施的類,但我感興趣的建議爲替代方法(因爲我不是特別滿意上述任何選項)。

更新: 由斯內德的回答啓發,我現在已經添加了以下效用函數的幫助模塊:

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' 

UPDATE2: 我結束了添加第二個實用功能,幾乎與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) 

(是的,原來的構造函數的參數一個今天早些時候就走開了。)

回答

8

如果這是你要重複一個模式,我可能會使用:

# 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) 
+0

事實證明,我結束了這樣做,只有''format_iter(args)''調用,而不是內聯inv ''str.join'' – ncoghlan

8

我傾向於是,如果你不喜歡的代碼,把它藏在一個函數:

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) 
+0

接受,因爲這是爲我落得這樣做(見更新) – ncoghlan

+0

直接靈感哦,被接受的答案有一段時間,直到我的解決方案演變爲看起來更像是從AGF的建議:) – ncoghlan

0

我可能會不喜歡它:

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)))