Domanda

C'è un modo in Python per determinare se un oggetto ha qualche attributo? Ad esempio:

>>> a = SomeClass()
>>> a.someProperty = value
>>> a.property
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: SomeClass instance has no attribute 'property'

Come puoi sapere se a ha l'attributo proprietà prima di usarlo?

È stato utile?

Soluzione

Prova hasattr () :

if hasattr(a, 'property'):
    a.property

EDIT: vedi la risposta di zweiterlinde , che offre buoni consigli su come chiedere perdono! Un approccio molto pitonico!

La pratica generale in Python è che, se è probabile che la proprietà sia presente per la maggior parte del tempo, è sufficiente chiamarla e lasciare che l'eccezione si propaghi oppure intercettarla con un blocco try / tranne. Questo sarà probabilmente più veloce di hasattr . Se è probabile che la proprietà non ci sia la maggior parte del tempo, o non sei sicuro, l'utilizzo di hasattr sarà probabilmente più veloce rispetto alla caduta ripetuta in un blocco di eccezioni.

Altri suggerimenti

Come Jarret Hardie ha risposto, hasattr farà il trucco. Vorrei aggiungere, tuttavia, che molti nella comunità di Python raccomandano una strategia di "più facile chiedere perdono che permesso" (EAFP) anziché "guardare prima di saltare" (LBYL). Vedi questi riferimenti:

EAFP vs LBYL (era Re: un po 'deluso finora)
EAFP vs. LBYL @Code Like a Pythonista: Idiomatic Python

vale a dire:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

... è preferito a:

if hasattr(a, 'property'):
    doStuff(a.property)
else:
    otherStuff()

Puoi usare hasattr () o catturare AttributeError , ma se vuoi davvero il valore dell'attributo con un valore predefinito se non c'è, il migliore l'opzione è solo per usare getattr () :

getattr(a, 'property', 'default value')

Penso che quello che stai cercando sia hasattr . Tuttavia, consiglierei qualcosa del genere se si desidera rilevare proprietà python -

try:
    getattr(someObject, 'someProperty')         
except AttributeError:
    print "Doesn't exist"
else
    print "Exists"

Lo svantaggio qui è che vengono catturati anche gli errori di attributo nel codice __get__ delle proprietà.

Altrimenti, do-

if hasattr(someObject, 'someProp'):
    #Access someProp/ set someProp
    pass

Documenti: http://docs.python.org/library/functions.html
Attenzione:
Il motivo della mia raccomandazione è che hasattr non rileva le proprietà.
Link: http://mail.python.org/pipermail/python -dev / 2005-dicembre / 058498.html

Secondo pydoc, hasattr (obj, prop) chiama semplicemente getattr (obj, prop) e rileva delle eccezioni. Quindi, è altrettanto valido racchiudere l'accesso all'attributo con un'istruzione try e catturare AttributeError come usare in anticipo hasattr ().

a = SomeClass()
try:
    return a.fake_prop
except AttributeError:
    return default_value

Vorrei suggerire di evitare questo:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

L'utente @jpalecek l'ha menzionato: se si verifica un AttributeError all'interno di doStuff () , ci si perde.

Forse questo approccio è migliore:

try:
    val = a.property
except AttributeError:
    otherStuff()
else:
    doStuff(val)

A seconda della situazione, puoi verificare con isinstance che tipo di oggetto hai e quindi utilizzare gli attributi corrispondenti. Con l'introduzione di classi di base astratte in Python 2.6 / 3.0 questo approccio ha diventano anche molto più potenti (in pratica gli ABC consentono un modo più sofisticato di scrivere l'anatra).

Una situazione in cui ciò sarebbe utile sarebbe se due oggetti diversi hanno un attributo con lo stesso nome, ma con significato diverso. L'uso di hasattr potrebbe quindi portare a strani errori.

Un bell'esempio è la distinzione tra iteratori e iterabili (vedi questa domanda). I metodi __iter__ in un iteratore e in un iterabile hanno lo stesso nome ma sono semanticamente abbastanza diversi! Quindi hasattr è inutile, ma isinstance insieme a ABC fornisce una soluzione pulita.

Tuttavia, sono d'accordo che nella maggior parte dei casi l'approccio hasattr (descritto in altre risposte) è la soluzione più appropriata.

Spero che ti aspetti hasattr (), ma cerca di evitare hasattr () e preferisci getattr (). getattr () è più veloce di hasattr ()

utilizzando hasattr ():

 if hasattr(a, 'property'):
     print a.property

stesso qui sto usando getattr per ottenere proprietà se non c'è proprietà che non ne restituisce nessuna

   property = getattr(a,"property",None)
    if property:
        print property

MODIFICA : questo approccio presenta serie limitazioni. Dovrebbe funzionare se l'oggetto è iterabile . Si prega di controllare i commenti qui sotto.

Se stai usando Python 3.6 o superiore come me, c'è una comoda alternativa per verificare se un oggetto ha un attributo particolare:

if 'attr1' in obj1:
    print("attr1 = {}".format(obj1["attr1"]))

Tuttavia, non sono sicuro di quale sia l'approccio migliore in questo momento. usando hasattr () , usando getattr () o usando in . I commenti sono ben accetti.

Ecco un approccio molto intuitivo:

if 'property' in dir(a):
    a.property

Puoi verificare se oggetto contiene attributi usando il metodo incorporato hasattr .

Ad esempio, se l'oggetto è a e si desidera verificare l'attributo stuff

>>> class a:
...     stuff = "something"
... 
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False

La stessa firma del metodo è hasattr (oggetto, nome) - > bool che significa se oggetto ha attributo che viene passato al secondo argomento in hasattr di quello che dà booleano True o False in base alla presenza dell'attributo name nell'oggetto.

Questo è super semplice, basta usare dir( oggetto )
Questo restituirà un elenco di tutte le funzioni e gli attributi disponibili dell'oggetto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top