What is the return value when implementing __contains__?

Question

When implementing __contains__() for a class, what is the proper return value to use?

Answer

The __contains__() method should always either return the values True or False to indicate whether the object “contains” the item being checked. How the class implements that check is dependent on the data contained in the class. However, the method should always return either True or False. If the method returns any other value, Python will try to convert or interpret the value as True or False and the resulting behavior may be unexpected.

9 Likes

Why when I try to use contains like below its not working at the end of the code:

print(contains(d_and_p,“Donelli”))

It gives a NameError that ‘contains’ is not defined

what project or exercise is this? Please share the url

magic methods (__contains__() is a magic method) are rarely called directly.

usually it involves using the in operator:

https://stackoverflow.com/questions/1964934/what-does-contains-do-what-can-call-contains-function

3 Likes

d_and_p = LawFirm(“Injury”, [“Donelli”, “Paderewski”])
print(“Donelli” in d_and_p)

prints True

4 Likes

we use in syntax in __contain__method

def __contains__(self, lawyer):
    return lawyer in self.lawyers

and again use (in) syntax of class instance name I think we should bypass in syntax to say we truly created class like , python built in class ,

for instance when we use in syntax for a list , do list object’s contain method has again … in … syntax inside it ? where this in syntax chain ends ?

Why should I use double underscore in contains? If I don’t, the method returns the same output:

class LawFirm:
  def __init__(self, practice, lawyers):
    self.practice = practice
    self.lawyers = lawyers

  def __len__(self):
    return len(self.lawyers)
  
  def contains(self, lawyer):
    return lawyer in self.lawyers
    
d_and_p = LawFirm("Injury", ["Donelli", "Paderewski"])

print(d_and_p.contains("Donelli"))
2 Likes

the double underscore makes a method “magic”.

the __contains__ magic method is used when we use the in operator. So if you implement __contains__ you could do:

"Donelli" in d_and_p
2 Likes

[quote=“beta3360213127, post:4, topic:361690”]
print(“Donelli” in d_and_p)

In Dunder Methods II whenever I attempt to reap the benefits of the __contains__ magic method and try and print a membership test.

Precisely as you have stated print(“Donelli” in d_and_p)

I get the following error message:
File "script.py", line 11 print(“Donelli” in d_and_p) ^ SyntaxError: invalid character in identifier

I also get an error when I attempt to use a newly instantiated LawFirm instance to access the contains method via:

print(d_and_p.contains("Donelli")

I get the following error

AttributeError: 'LawFirm' object has no attribute 'contains'

This is what my code looks like at this moment.

I have what I thought was a perfectly acceptable __contains__ method. What am I missing?

can you copy paste your code to the forum? debugging from screenshots is very difficult

on line 11, you use smart quotes. You should use quotation marks.

May be because this syntax is for strings… And for lists, as we have a list of lawyers, we should use “element IN list” syntax…?

Using the __contains__() method permits us to use the in keyword on an object instance by abstracting it away.

 print ("Donelli" in d_and_p.lawyers)

becomes,

print ("Donelli" in d_and_p)
1 Like

Yes, I’ve got, thank you, but I was trying to answer to the second part of [pmgriego]'s (https://discuss.codecademy.com/u/pmgriego) question.( “Donelli” in d_and_p) did not work because of “wrong” quotes, as stetim94 has pointed; and I wrote about the possible reason why syntax (d_and_p.contains(“Donelli”)) did not work also. Can you tell please your expert opinion about the original question? It’s interesting…

There is no such attribute contains. The dunder method permits the use of the in keyword directly on the instance.

Consider,

>>> class Foo:
	def __init__(self, foo, bar):
		self.foo = foo
		self.bar = bar

		
>>> a = Foo('faz', 'baz')
>>> 'foo' in a
Traceback (most recent call last):
  File "<pyshell#134>", line 1, in <module>
    'foo' in a
TypeError: argument of type 'Foo' is not iterable
>>> 

Now,

>>> class Foo:
	def __init__(self, foo, bar):
		self.foo = foo
		self.bar = bar
	def __contains__(self, attr):
		return attr in dir(self)

	
>>> a = Foo('faz', 'baz')
>>> 'foo' in a
True
>>> 

which is the same as,

>>> hasattr(a, 'foo')
True
>>> 
1 Like

Thank you! Your explanations are perfect as always.

1 Like

Succinct and perfect explanation of the functions of the method. Thank you.

1 Like