L'implementazione python2 di hasattr è abbastanza ingenuo, si cerca solo di accedere a tale attributo e vedere se solleva un'eccezione oppure no.
Sfortunatamente, ciò significa che eventuali eccezioni non gestite all'interno delle proprietà verranno inghiottite e gli errori in tale codice potrebbero andare persi. Per aggiungere la beffa al danno, quando hasattr mangia l'eccezione, verrà restituita anche una risposta errata (qui l'attributo a.foo
è, quindi il risultato dovrebbe essere restituito True
se necessario).
In python3.2 +, è stato corretto il comportamento:
hasattr(object, name)
Gli argomenti sono un oggetto e una stringa. Il risultato è True
se la stringa è il nome di uno degli attributi dell'oggetto, False
in caso contrario. (Questo viene implementato chiamando getattr(object, name)
e vedere se si solleva un AttributeError
o no.)
La correzione è here, ma purtroppo che il cambiamento non ha backport.
Se il comportamento di python2 causa problemi, considerare di evitare l'uso di hasattr
; puoi invece provare/eccetto lo getattr
, rilevando solo l'eccezione AttributeError
e lasciando che altri aumentino.
Nonostante la citazione dai documenti Python, il comportamento di 'hasattr' può ancora essere considerato strano. È vero che le eccezioni arbitrarie all'interno di una proprietà non causano più l'attributo da considerare assente (ma piuttosto vengono sollevate direttamente nella faccia del chiamante), ma se un "AttributeError" proviene da qualche parte all'interno della proprietà, il risultato di 'hasattr' sarà comunque essere 'False'. Questo potrebbe non essere intenzionale. (O può, così una proprietà può determinare se vuole essere "lì"). In ogni caso, l'esecuzione della proprietà suona male per me in primo luogo, considerando gli effetti collaterali ecc. –
Non c'è un modo veramente diretto per determinare se un attributo 'AttributeError' è stato sollevato dall'attributo - ottenere la macchina stessa, o dal codice in una proprietà. – kindall