3

I am a python beginner and was reading about dunder methods. Is it somehow possible to change the dunder methods of classes like int or str?

For instance, can I somehow change dunder method __add__ of int class to perform multiplication instead of addition? So if I type 3 + 4, output is 12?

khelwood
  • 55,782
  • 14
  • 81
  • 108
Ajay Jain
  • 33
  • 4
  • 1
    Does this answer your question? [Can I add custom methods/attributes to built-in Python types?](https://stackoverflow.com/questions/4698493/can-i-add-custom-methods-attributes-to-built-in-python-types) – Tomerikoo Jan 05 '21 at 15:56
  • 1
    Short answer is - no. Even you did something hacky like the accepted answer in the link above, you will still need to do `int(3) + 4`. There is no way of changing literals' behavior without changing Python itself (making your own implementation) – Tomerikoo Jan 05 '21 at 16:01
  • Also related: [Can literals in Python be overridden?](https://stackoverflow.com/questions/19083160/can-literals-in-python-be-overridden) – Tomerikoo Jan 05 '21 at 16:03

2 Answers2

3

You can subclass, but it's worth pointing out this is likely a bad idea since no-one reasonably expects add to perform multiplication:

class FunkyInt(int):
    def __add__(self, other):
        return FunkyInt(self * other)

f = FunkyInt(3)
print(f + 4)
# 12
Chris_Rands
  • 38,994
  • 14
  • 83
  • 119
  • Thanks for your answer. But as @Tomerikoo pointed out, I wanted to somehow be able to do `3 + 4` but `FunkyInt(3) + 4` is the only possible way. – Ajay Jain Jan 05 '21 at 16:28
  • @AjayJain why would you want to do that? Explain your use case – Chris_Rands Jan 05 '21 at 16:44
  • Actually I was just playing around with dunder methods and thought if this thing is possible. I am sorry if you think I wasted your time. – Ajay Jain Jan 05 '21 at 16:48
  • This question is fine. I've got a use case. I want to override dict.__add__ so when you use + to add keys to a dictionary (and obv. through an error if key already exists) – AER May 27 '22 at 15:23
0

My best guess would be that you can't (which is in line with this answer). I tried a couple of options and got the same error with in-built classes. As per Chris_Rands' answer, you can always create a Class inheriting from the in-built object in question.

>>> int.__add__ = int.__mul__
int.__add__ = int.__mul__                                                                                                                                                                                                                                                                                                                                                                                                             
Traceback (most recent call last):                                                                                                                                                                                                                                                                                                                                                                                                    
  File "<stdin>", line 1, in <module>                                                                                                                                                                                                                                                                                                                                                                                                 
TypeError: can't set attributes of built-in/extension type 'int' 

and

>>> dict.__add__ = list.__add__                                                                                                                                                                                                                                                                                                                                                                                                       
dict.__add__ = list.__add__                                                                                                                                                                                                                                                                                                                                                                                                           
Traceback (most recent call last):                                                                                                                                                                                                                                                                                                                                                                                                    
  File "<stdin>", line 1, in <module>                                                                                                                                                                                                                                                                                                                                                                                                 
TypeError: can't set attributes of built-in/extension type 'dict'

Looks like the error is not a syntax problem but more explicitly you can't redefine built-in methods.

AER
  • 1,549
  • 19
  • 37