FAQ: Learn Python: Inheritance and Polymorphism - Dunder Methods II

This community-built FAQ covers the “Dunder Methods II” exercise from the lesson “Learn Python: Inheritance and Polymorphism”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Computer Science

FAQs on the exercise Dunder Methods II

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

2 posts were split to a new topic: Why do we need a dunder method if list already has len()?

If I implement the dunder method __len__ like this:

 def __len__(self):
    return len(self.lawyers)

I can call it successfully like this:

print(len(d_and_p))

but this returns an error:

print(__len__(d_and_p))

here is the error:

Traceback (most recent call last):
  File "script.py", line 15, in <module>
    print(__len__(d_and_p))
NameError: name '__len__' is not defined

It seems like the opposites should be the case. What is going on here?

thanks!

If you’ve defined a new method inside your class definition remember that it’s bound to that class (it’s not a regular function and cannot be immediately accessed in the global namespace) and is an attribute of any instances you create from it and can be accessed like so: instance.method(). You’re treating it like a function which it is not. You’d have to then write your own function which calls the .__len__ method of an instance passed to it to make it work in the way you did.

Calling that method with the built-in, len() is the accepted way and you’d probably raise a few eyebrows if you did it any other way.

1 Like

class LawFirm:

def init(self, practice, lawyers):

self.practice = practice

self.lawyers = lawyers  

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

if “Donelli” in d_and_p.lawyers:

print(“HEy this also works”)

print(len(d_and_p.lawyers))

In the exercise if i use this method the output remains the same and no error is given so i am having a hard time understanding the use of these methods as just adding the attribute seems easier than creating a dunder method

So trying to use the iter dunder method and not really sure how it works and what i can do with it in this context, nothing was givin in the example other than syntax and it was not used in the problem. I added it to my code but not sure what to do with it or the syntax on how to use it.


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

  

  def __iter__(self):

    return iter(self.lawyers)

d_and_p = LawFirm("Injury", ["Donelli", "Paderewski"])

print (len(d_and_p))

print ("Donelli" in d_and_p)

I don’t seem to understand the usage of user.username in the below code. Can’t we just print user?

for user in can_edit:
print(user.username)

You’ve created each user as a new object so passing an instance of User to print will give you a representation of the object stored instead of the exact attribute you’re looking for that probably looks something like the following-

Out: <__main__.User object at 0x7ffffffffff>

Not too helpful when you want to find which users have editing permissions so using the .username attribute is the way to go.

What most of the built-ins have, and what you can implement yourself, are dunder methods to provide cleaner string representations when the object is printed. The __str__ method in particular could be used here to return the user.username and then print would do what you want-
https://docs.python.org/3/reference/datamodel.html#object.str

__repr__ is a similar method but it is designed more for debugging so in this example __str__ is more appropriate (repr should return something more like User("diana") which is a valid Python expression that could recreate the given object.
https://docs.python.org/3/reference/datamodel.html#object.repr

1 Like

Thank you very much for your prompt reply! I get it now :slight_smile:

1 Like