Is it possible to overload operators for native datatypes?

左心房为你撑大大i 提交于 2021-02-07 17:27:46

问题


For example, if I try to do:

a_string + an_int

... where a_string is type 'str' and an_int is type 'int', or:

an_int + a_string

There would be a TypeError because there is no implicit conversion of the types. I understand that if I were using my own subclasses of int and string, I would be able to overload the __add__() method in my classes to achieve this.

However, out of curiosity, I would like to know: would it be possible to overload the + operator in the class definitions of int and str, so that __add__(int,str) and __add__(str,int) automatically concatenate them as strings?

If not, what are the reasons why a programmer should not overload the operators for a native datatype?


回答1:


In general, without reverting to the C-level API, you cannot modify attributes of builtin types (see here). You can, however, subclass builtin types and do what you want on the new types. For the question you specifically asked (making the addition string based), you'd modify __add__ and __radd__:

class Int(int):
    def __add__(self, other):
        return Int(int(str(self) + str(other)))

    def __radd__(self, other):
        return Int(str(other) + str(self))

>>> Int(5) + 3
53

>>> 3 + Int(5) + 87
3587



回答2:


As pointed out above, you can't (unless you are up to building your own Python implementation). That is, you cannot change the way '1'+1 is handled if encountered in code. But you can mess with builtin functions however you please:

>>> int = str
>>> type(1)
<class 'int'>
>>> type('1')
<class 'str'>
>>> int(1)
'1'
>>> type(int(1))
<class 'str'>

It's little more than an enlightening example of first-class functions' awesomeness, thoug. Any changes you make stay in a namespace you are making them in. Consider this:

>>> str=int
>>> str('1')
1
>>> str('asd')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'asd'
>>> input()
2
'2'
>>> 

You are using whatever you put in str, in this case int. But input() knows better and falls back to the builtins. There may be some weird trick with closures that'll make it refer to your implementation, but I can't find it. By the way, original str is in __builtins__.str, should you need it back.

Pulling the same trick on builtin's methods doesn't work:

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


来源:https://stackoverflow.com/questions/38831695/is-it-possible-to-overload-operators-for-native-datatypes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!