On Sun, 26 Oct 2008 22:44:41 +0100, Listemessaggi CoPlast <[EMAIL PROTECTED]> wrote:
> Ma se come detto, faccio l'overloading di questo operatore, cioè con: > > class Commuter: > def __init__(self, val): > self.val = val > def __getattr__(self, nome): > print("BO") > > se scrivo: > > c = Commuter(23) > print(c) > > ottengo: > > BO > Traceback (most recent call last): > File "libreria.py", line 83, in ? > print(c) > TypeError: 'NoneType' object is not callable > > > Osservo che ha scritto BO segno che è passato per __getattr__. Ma > perché? > Forse viene interpretato come una qualificazione di un attributo di nome > "" (senza nome)? > Se su def __getattr__(self, nome): ci inserisco un print(nome) ottengo: > __str__ > Ciò mi mette ancora più in confusione. __getattr__ viene invocato quando un attributo non viene trovato nell'oggetto. Quando fai "print c", Python chiede a 'c' il metodo __str__, che viene usato per convertire l'oggetto in stringa. Poiché non hai definito __str__, questo viene chiesto a __getattr__ (come verifichi). Nella tua definizione di __getattr__ c'è un "return None" implicito alla fine: Python riceve qualcosa dal tuo oggetto e pensa che sia il metodo __str__: quindi prova ad invocarlo. Quello che fa invece è provare a invocare None(), che risulta nell'errore che riporti. Il problema di come hai definito tu __getattr__ è che "va sempre tutto bene", salvo poi che il runtime pensa di avere un oggetto callable con la semantica di __str__ mentre invece ha un None. Dovresti implementare il tuo __getattr__ in maniera da rispondere solo a quello che si aspetta e dare errore negli altri casi. Per esempio: class Commuter: def __init__(self, val): self.val = val def __getattr__(self, nome): print(nome) raise AttributeError("%s has no attribute '%s'" % (self.__class__.__name__, nome)) >>> print c __str__ __repr__ <__main__.Commuter instance at 0xb78397cc> >>> c.ciao ciao ciao --------------------------------------------------------------------------- <type 'exceptions.AttributeError'> Traceback (most recent call last) /home/piro/<ipython console> in <module>() <type 'exceptions.AttributeError'>: Commuter has no attribute 'ciao' > Comunque il mio obiettivo sarebbe quello di usare __radd__ solo che il > mio oggetto ha sia la __radd__ che la __getattr__ e quest'ultima fa in > modo che la __radd__ non riceva correttamente l'istanza del mio oggetto > impedendomi di usarla. La semantica è quella di invocare __getattr__ solo se l'attributo cercato non viene trovato, quindi __radd__ non dovrebbe conflittare: dovrebbe essere cercato *prima* di getattr. Probabilmente, per come poi usi la tua classe, non è __radd__ ad essere invocato. La strada per il debug l'hai azzeccata: un print nel __getattr__ va bene. Aggiungi il raise AttributeError alla fine e scoprirai qual'è il metodo che ti serve. -- Daniele Varrazzo - Develer S.r.l. http://www.develer.com _______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python