2015-09-26 12 views
9

Ho una piccola classe che è la seguente:Verificando una variabile appartiene ad una classe in pitone

class Gender(object): 
    MALE = 'M' 
    FEMALE = 'F' 

Ho una variabile parametro che può essere solo M o F .To assicurare che è solo che, faccio la seguente:

>>> parameter = 'M' 
>>> if parameter not in (Gender.MALE, Gender.FEMALE) 
...  print "Invalid parameter" 
... 
Invalid parameter 
>>> 

Ora ho una classe che contiene tutti gli Stati Uniti come segue:

class States(object): 
    ALABAMA = 'AL' 
    ALASKA = 'AK' 
    ARIZONA = 'AZ' 
    ARKANSAS = 'AR' 
    CALIFORNIA = 'CA' 
    COLORADO = 'CO' 
    CONNECTICUT = 'CT' 
    DELAWARE = 'DE' 
    DISTRICTOFCOLUMBIA = 'DC' 
    .... 
.... 

Come l'esempio di cui sopra, il mio parametro ora è AL .Tuttavia, dato che ci sono 50 stati negli Stati Uniti, non posso usare praticamente l'tupla con 50 variabili come ho usato above.Is c'è un modo migliore di fare questo ? Ho letto di isinstance ma non mi ha dato i risultati attesi.

+2

Se si sta utilizzando Python 3, dare un'occhiata a [enum] (https: //docs.python. org/dev/library/enum.html) –

+0

dovresti usare un [enum] (https://stackoverflow.com/questions/36932/how-can-i-represent-an-enum-in-python) – shx2

+0

E IIRC ci dovrebbe essere una ricetta di Python 2 per le enumerazioni da qualche parte. –

risposta

8

è possibile utilizzare la proprietà __dict__ che compone una classe, ad esempio:

In [1]: class Foo(object): 
    ...:  bar = "b" 
    ...:  zulu = "z" 
    ...:  
In [2]: "bar" in Foo.__dict__ 
Out[2]: True 

O come si sta cercando i valori utilizzare __dict__.values():

In [3]: "b" in Foo.__dict__.values() 
Out[3]: True 

Come Peter Wood segnala che è possibile utilizzare anche il dispositivo integrato vars() per recuperare il numero __dict__:

In [12]: "b" in vars(Foo).values() 
Out[12]: True 

La proprietà __dict__ viene utilizzata come namespace for classes e così restituirà tutti i metodi, magic methods e proprietà private sulla classe e, in modo per la robustezza si potrebbe desiderare di modificare la sua ricerca un po 'per compensare.

Nel tuo caso, si potrebbe desiderare di utilizzare un classmethod, come ad esempio:

class States(object): 
    ALABAMA = "AL" 
    FLORIDA = "FL" 

    @classmethod 
    def is_state(cls, to_find): 
     print(vars(cls)) 
     states = [val for key, val in vars(cls).items() 
        if not key.startswith("__") 
        and isinstance(val, str)] 
     return to_find in states 

States.is_state("AL") # True 
States.is_state("FL") # True 
States.is_state("is_state") # False 
States.is_state("__module__") # False 
+1

Attenzione, questo restituirà i falsi positivi se esiste un metodo che corrisponde anche alla chiave. –

+0

Nessun metodo nella mia classe, quindi questo dovrebbe essere sufficiente ... grazie – Amistad

+0

Nota che questo non funzionerà con '__slots__', un modo migliore è usare' hasattr', ma è diverso da cercare nel dizionario della classe come apparirà ovunque nell'albero dell'eredità. –

6

Perché non usi un dizionario? È molto più semplice e le ricerche saranno anche più semplici.

states = {'AL': 'Alabama', 'AK': 'Alaska' ... } 
test_state = 'Foo' 

if test_state not in states.keys(): 
    print('{} is not valid input'.format(test_state)) 
+1

Non hai nemmeno è necessario usare '.keys()', dato che 'in' controlla comunque i tasti. 'se test_state non si trova in stati:'. –

+1

Hai ragione - Ho solo l'abitudine di usare '.keys()'. –

+1

Se si utilizza il costruttore 'dict', è possibile utilizzare gli argomenti parola chiave invece di creare stringhe. per esempio. 'dict (AL = 'Alabama', AK = 'Alaska')' –

5

Io suggerirei di usare Enum di definire sia Gender e States.
Enum se parte della libreria standard su Python 3. Se sei su Python 2 usa enum34, installa con pip install enum34.

from enum import Enum 
class States(Enum): 
    ALABAMA = 'AL' 
    ALASKA = 'AK' 
    ARIZONA = 'AZ' 
    ARKANSAS = 'AR' 
    CALIFORNIA = 'CA' 
    COLORADO = 'CO' 
    CONNECTICUT = 'CT' 
    DELAWARE = 'DE' 
    DISTRICTOFCOLUMBIA = 'DC' 
    ... 

Poi si può verificare se una variabile è uno degli stati da

isinstance(variable, States) 
+1

sembra fantastico ... comunque .. sono ancora in 2.7 .. – Amistad

+0

@Amistad aggiornerò la risposta per python 2.7. – Forge

+0

@Amistad è ora aggiornato. – Forge

Problemi correlati