2013-10-22 3 views
15

Si consideri il seguente codice:weakref e __slots__

from weakref import ref 

class Klass(object): 
    # __slots__ = ['foo'] 
    def __init__(self): 
     self.foo = 'bar' 

k = Klass() 
r = ref(k) 

funziona, ma quando ho rimuovere il commento dalla __slots__ rompe con TypeError: "cannot create weak reference to 'Klass' object" sotto Python 2.6.

Per favore, qualcuno sa se questo è un limite intrinseco di Python e __slots__ o se si tratta di un bug? Come aggirarlo?

risposta

19

Senza una variabile __weakref__ per ciascun esempio, classi definiscono __slots__ non supportano riferimenti deboli alle sue istanze. Se è necessario un supporto di riferimento debole, aggiungere __weakref__ alla sequenza di stringhe nella dichiarazione __slots__.

Da Python documentation.

Se si aggiunge a __weakref____slots__, il codice funzionerà:

>>> from weakref import ref 
>>> 
>>> class Klass(object): 
>>>  __slots__ = ['foo', '__weakref__'] 
>>>  def __init__(self): 
>>>   self.foo = 'bar' 
>>> k = Klass() 
>>> k 
=> <__main__.Klass object at ...> 
>>> r = ref(k) 
>>> r 
=> <weakref at ...; to 'Klass' at ...> 
4

È necessario aggiungere __weakref__ alla lista degli slot. È uno degli __slots__ quirks. Prima del 2.3, anche questo non ha funzionato, ma per fortuna la tua versione non è così vecchia.