60

Here is my code:

class a(object):
    d='ddd'
    def __contains__(self):
        if self.d:return True
b=a()
print b.contains('d')  # error
print contains(b,'d')  # error
Chris Martin
  • 30,334
  • 10
  • 78
  • 137
zjm1126
  • 63,397
  • 81
  • 173
  • 221

5 Answers5

101

Like all special methods (with "magic names" that begin and end in __), __contains__ is not meant to be called directly (except in very specific cases, such as up=calls to the superclass): rather, such methods are called as part of the operation of built-ins and operators. In the case of __contains__, the operator in question is in -- the "containment check" operator.

With your class a as you present it (except for fixing your typo, and using True instead of true!-), and b as its instance, print 'x' in b will print True -- and so will any other containment check on b, since b always returns True (because self.d, a non-empty string, is true).

Slothworks
  • 1,083
  • 14
  • 18
Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
28

to get your code to do something (although nothing useful):

class a(object):

    d = 'ddd'

    def __contains__(self, m):
        if self.d: 
            return True

b = a()

>>> 'd' in b
True

The docs.

Julius
  • 886
  • 8
  • 13
cobbal
  • 69,903
  • 20
  • 143
  • 156
26

__contains__ method defines how instances of class behave when they appear at right side of in and not in operator.

class Person(object):
      def __init__(self,name,age):
          self.name = name
          self.age = age
      def __contains__(self,param1):
          return True if param1 in self.__dict__.keys() else False

>>> p = Person('Robby Krieger',23)
>>> 'name' in p
True  
Azat Ibrakov
  • 9,998
  • 9
  • 38
  • 50
vijay shanker
  • 2,517
  • 1
  • 24
  • 37
  • 15
    More simply, you could write for `__contains__`: `return param1 in self.__dict__.keys()` – fralau Aug 21 '19 at 16:53
  • `param in dict` is sufficient to check if param is a key in dict. There is no need to call keys() on the dict beforehand – julaine Apr 24 '23 at 13:19
9
if self.d:return true

self.d is the string 'ddd'. Non-empty strings are always truthy: when you use if on 'ddd' it will always act as if you'd said if True:.

I think what you probably meant is:

def __contains__(self, item):
    return item in self.d

in is the operator that calls the __contains__ method behind the scenes.

bobince
  • 528,062
  • 107
  • 651
  • 834
9

Lets see a very simple example of magic method __contains__ :

Suppose I have class Player and my __init__ method takes one string argument name. In main I have created an object (obj1) of class Player.

Now if I want to know if my obj1 (in this case attribute name of obj1) contains a particular string, substring or an alphabet, I have to implement __contains__ method as shown in the example.

If my class has __contains__ method I can call built-in operator in on my custom objects as shown in the example.

   class Player():

    def __init__(self, name):
        self.name=name

    def __contains__(self, substring):
        if substring in self.name:
            return True
        else:
            return False

obj1=Player("Sam")
print ('am' in obj1)    ----> True
print ('ami' in obj1)   ----> False
N Randhawa
  • 8,773
  • 3
  • 43
  • 47