2011-08-16 16 views
13

, ben başlangıçta aşağıdaki satırlar boyunca bir __repr__ yöntemi bilgiler arasında büyük biçimlendirilmiş dize bir parçası olarak:dahil biçimlendirilmiş iterable geçenlerde bir sınıf yazarken

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

'{r!}' Böyle pasajı hissediyor tekrarlanması yanlış ve bu sınıfa daha fazla argüman eklediğimde sürdürmek için sıkıcı olurdu. Ancak, benim için gerçekleşen daha güçlü alternatifler, ya zarafet için herhangi bir ödül kazanmayacak.

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

Şu anda son örneği kullanarak sınıfı uyguladık ama önerileri ilgileniyorum: str.join ile ayrı ayrı argümanlar Biçimlendirme

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

:

programlı biçim dizesi Bina Alternatif yaklaşımlar için (özellikle yukarıdaki seçeneklerden hiç memnun değilim).

Güncelleme: Neredeyse, Ben ikinci bir yarar fonksiyonunu ekleyerek sona erdi:

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: Ned'in cevap esinlenerek , şimdi bir yardımcı modülüne sonrasında kamu işlevi ekledik

def call_repr(name, *args): 
    return "{}({})".format(name, format_iter(args)) 

Yani aslen rencide __repr__ fonksiyonu: AGF yanıtında bir aynıdır

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

(Evet, orijinal Yapıcı, bir, bugün erken saatlerde gitti.)

cevap

8

, muhtemelen kullanmayı tercih ediyorum:

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

veya

# 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

Bu ortaya çıktığında, bunun yerine sadece bir '' format_iter (args) '' çağrısı yaparak satır içi davet str.join' – ncoghlan

8

Benim eğim kodu beğenmezseniz, bir işlevde gizlemek, şöyle olacaktır: şimdi şöyle görünür: Bu tekrarlanmasını gidiyoruz bir desen ise

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

Kabul, bu şimdiye (güncelleştirmeyi bakınız) – ncoghlan

+0

bunu kadar sona erdi doğrudan ilham beri Eh, bir süreliğine kabul edilen cevap, çözümüm agf'ın önerisine benzeyene kadar evrimleşene kadar geldi :) – ncoghlan

0

Ben seversiniz olabilir:

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

ya:

_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))) 
İlgili konular