2010-05-18 14 views
12

Python'da bir kapsayıcı türü yazdım ve kabın kendisinin içerdiği durumu doğru işleyen sağlam bir __repr__ yöntemi yazmaya çalışıyorum.Yinelemeli repr() 'leri Python'da nasıl kullanırım?

Örneğin, aşağıda list dahili yaptığı da budur: CPython için C ile yazılmış

>>> x = [] 
>>> x.append(x) 
>>> repr(x) 
'[[...]]' 

Konteyner tipleri Py_ReprEnter ve Py_ReprLeave kullanarak bu işlevselliği elde edebilirsiniz. Saf-Python'da eşdeğer bir işlevsellik var mı, yoksa kendi kendime mi ihtiyacım var?

cevap

6

Kendi oluşturabilir, ancak onu gerektiği gibi yapmak istiyorsanız bir ağrı biraz: nesnenin kendisi olduğunu parçacığı için güvenli değil çünkü bir ‘repr'd ediliyor’ işaretleyici bayrağı depolamak olmamalıdır. Bunun yerine, tekrarlanan örneklerin bir iş parçacığı yerel kümesini saklayabilirsiniz.

bir çok daha ucuz bir çözüm, dahili repr özyineleme bakımı, mesela .:

def __init__(self, *list): 
    self._list= list 
def __repr__(self): 
    return 'mything('+repr(self._list)[1:-1]+')') 

alır sürece gibi bir kendi kendini yineleme döngüsünde nesne Py_ReprEnter gerçekleşmesi neden olan bir bağımlı repr olduğunu tam bir döngü oluşturamaz.

İş parçacığı yerel örneklerini nasıl oluştururum? threading modül ile

: Python 3 kullanıyorsanız, reprlib.recursive_repr dekoratör yararlanabilirler

class MyThing(object): 
    _local= threading.local() 
    _local.reprs= set() 

    def __repr__(self): 
     reprs= MyThing._local.reprs 
     sid= id(self) 
     if sid in reprs: 
      return 'MyThing(...)' 
     try: 
      reprs.add(sid) 
      return 'MyThing(%r)' % self.something 
     finally: 
      reprs.remove(sid) 
+0

Ne yazık ki, repr dizesini dinamik olarak hesaplamalıyım, bu nedenle yerleşik repr() 'ye tanımladığınız şekilde bağlı olamam. Konu yerel bir örnek kümesi nasıl oluştururum? –

+0

@DanielStutzbach, neden denemede/son olarak bloke oldu? – akaRem

+1

@akaRem: 'self.something', özyineleme içeren bazı daha karmaşık işler için bir yer tutucudur. Kötü bir günde orada bir şey istisnaya neden olabilir. Böyle bir durumda, "reprs" listesinin geri çekildiğinde temizlendiğinden emin olmak isteriz, aksi takdirde hatalar biriktikçe örnek biriktirir ve bu da MyThing'in "MyThing" olarak çalışmasına neden olur (...) “Yineleme olmasa bile. – bobince