Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if a variable belongs to a class in python

I have a small class which is as follows :

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

I have a parameter variable which can be only M or F.To ensure it is only that, I do the following :

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

Now I have a class which contains all the States in USA as follows:

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

Like the example above,my parameter now is AL.However, since there are 50 states in the USA,I cannot practically use the tuple with 50 variables like I used above.Is there a better way of doing this ? I did read about isinstance but it did not give me the expected results.

like image 432
Amistad Avatar asked Sep 26 '15 11:09

Amistad


People also ask

How do you tell if an object is a class Python?

In Python, the built-in functions type() and isinstance() help you determine the type of an object. type(object) – Returns a string representation of the object's type. isinstance(object, class) – Returns a Boolean True if the object is an instance of the class, and False otherwise.

How do I check if a variable is defined in Python?

Python doesn't have a specific function to test whether a variable is defined, since all variables are expected to have been defined before use, even if initially assigned the None object.

What is used to check whether an object O is an instance of class A?

The isinstance() function checks if the object (first argument) is an instance or subclass of the class info class (second argument).

How do you check if a variable is a type?

You can use the typeof operator to check the variable. It returns a string which indicates the type of the unevaluated operand.


2 Answers

You could use the __dict__ property which composes a class, for example:

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

Or as you're searching for the values use __dict__.values():

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

As Peter Wood points out, the vars() built-in can also be used to retrieve the __dict__:

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

The __dict__ property is used as a namespace for classes and so will return all methods, magic methods and private properties on the class as well, so for robustness you might want to modify your search slightly to compensate.

In your case, you might want to use a classmethod, such as:

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

Update This clearly answer's the OPs question, but readers may also be interested in the Enum library in Python 3, which would quite possibly be a better container for data such as this.

like image 133
Ian Clark Avatar answered Sep 29 '22 19:09

Ian Clark


Why don't you use a dictionary? Its a lot simpler and lookups will be easier as well.

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

if test_state not in states.keys():
    print('{} is not valid input'.format(test_state))
like image 30
Burhan Khalid Avatar answered Sep 29 '22 19:09

Burhan Khalid