Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Is the reason we use dunder functions in classes...

Looking up the various dunder functions. It looks to me like maybe the reason we use the dunder functions when making classes but not functions: In functions dunders are already there behind the scenes AND in classes we need to be explicit because we are deliniating all the information ourselves???

Tagging Chris Freeman

1 Answer

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,426 Points

I'm sure you've heard "everything in Python is an object." This also means that everything derives from some class. Functions are no different, deriving from the class function. The "dunder" methods are built-in Python methods to the underlying class each having a specific purpose. Details on all the magic methods are in the docs.

It is possible to overwrite the magic methods on functions and classes. When new classes are defined it is common to overwrite some of the built-in methods (typically __init__) to create custom functionality but this is not required.

Using type() and dir() to inspect a trivial function, you can see the "dunder" magic methods:

# Trivial class
>>> class MyClass:
...     pass
... 
>>> dir(MyClass)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

# Trivial function
>>> def foo():
...     pass
... 
>>> foo()
>>> type(foo)
<class 'function'>
>>> >>> dir(foo)
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

The same is true for a simple integer:

>>> type(5)
<class 'int'>
>>> dir(5)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

Chris, that is a beautifully laid out answer. Thank you for that. re:

  • "It is possible to overwrite the magic methods on functions and classes."
  • I don't think I have seen dunders used on functions, only classes. (I get that there is a relation to what functions do and what classes do). But I think that Kenneth has only used dunders on objects like:
class trying_to_understand:
    __int__()  
#but not:
def im_still_foggy():
    do something or other

So, I think you are saying that dunders can be used on functions AND classes?

Chris Freeman
Chris Freeman
Treehouse Moderator 68,426 Points

My main point is that all objects, including functions, have built-in dunder methods. In classes, some of the dunder methods can be overridden with custom versions or can extend or modify the inherited method of the parent class method (using super()). In a normal function usage, it would be rare to modify an inherited method from the function class.