9

For primitive types I can use the if in : boolean check. But if I use the in syntax to check for the existence of a class member I get a NameError exception. Is there a way in Python to check without an exception? Or is the only way to surround in try except block?

Here is my sample code.

class myclass:
    i = 0
    def __init__(self, num):
        self.i = num

mylist = [1,2,3]
if 7 in mylist:
    print "found it"
else:
    print "7 not present"  #prints 7 not present


x = myclass(3)
print x.i       #prints 3

#below line NameError: name 'counter' is not defined
if counter in x:
    print "counter in x"
else:
    print "No counter in x"
moooeeeep
  • 31,622
  • 22
  • 98
  • 187
Angus Comber
  • 9,316
  • 14
  • 59
  • 107
  • Duplication of http://stackoverflow.com/questions/843277/how-do-i-check-if-a-variable-exists-in-python – Regenschein Jul 11 '13 at 10:57
  • @fordprefect While it's probably a duplicate, it's not a duplicate of that question. This is about object attributes, that question is about local and global variables. –  Jul 11 '13 at 11:23

4 Answers4

23

You can use hasattr

if hasattr(x, 'counter'):
    # whatever
Neuron
  • 5,141
  • 5
  • 38
  • 59
Jon Clements
  • 138,671
  • 33
  • 247
  • 280
12

The error you get is because you are using counter (a name) and not 'counter' (the string). However, even if you were to use 'counter' it would not do what you expect, you will get TypeError: argument of type 'a' is not iterable - that is you cannot iterate over your custom object.

Instead, use hasattr (thanks to Jon for the suggestion).

>>> x = A(3)
>>> x.i
3
>>> hasattr(x, 'counter')
False
>>> hasattr(x, 'i')
True
Neuron
  • 5,141
  • 5
  • 38
  • 59
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
2

You can make a __contains__ function in your class, which reports back what attributes are in the class using the in operator.

class myclass:

    def __init__(self, num):
        self.i = num

    def __contains__(self, attribute_name):
        return hasattr(self, attribute_name)

Then (almost) the same as your code would work well.

x = myclass(3)
print x.i       #prints 3

# prints 'No counter in x'
if 'counter' in x:
    print "counter in x"
else:
    print "No counter in x"

Note that you need to pass the string of the attribute name, rather than the attribute itself.

ijmarshall
  • 3,373
  • 2
  • 19
  • 13
  • Your contains idea is interesting but I think it is easier to just use hasattr directly. I didn't know about hasattr – Angus Comber Jul 11 '13 at 11:12
0

The correct answer to your question depends a bit on what you mean by a member existing in an object. If you mean, does an instance variable exist on a given object, use hasattr as other answers have explained.

However, if you're creating your own collection type and want to check for a specific value in its contents, then you'll want to give your class a __contains__ method. That magic method is called to implement the in operator. Here's a trivial example, where I simply wrap up a list in my own object.

class MyListWrapper(object):
    def __init__(self, iterable=[]):
        self.list = list(iterable)

    def __contains__(self, value):
        return value in self.list

Test session:

>>> m = MyListWrapper(["foo", "bar"])
>>> "foo" in m
True
Blckknght
  • 100,903
  • 11
  • 120
  • 169