是否可以重载本机数据类型的运算符?

Posted

技术标签:

【中文标题】是否可以重载本机数据类型的运算符?【英文标题】:Is it possible to overload operators for native datatypes? 【发布时间】:2016-12-14 09:00:52 【问题描述】:

例如,如果我尝试这样做:

a_string + an_int

...其中a_string 是'str' 类型,an_int 是'int' 类型,或者:

an_int + a_string

会有一个TypeError,因为没有类型的隐式转换。我知道如果我使用自己的 int 和 string 子类,我将能够在我的类中重载 __add__() 方法来实现这一点。

但是,出于好奇,我想知道:是否可以重载intstr 的类定义中的+ 运算符,以便__add__(int,str)__add__(str,int) 自动将它们连接为字符串?

如果不是,程序员不应该为原生数据类型重载运算符的原因是什么?

【问题讨论】:

blog.teamtreehouse.com/operator-overloading-python 感谢您的链接,它很好地解释了如何在用户定义的类中重载运算符。但是,我想知道是否可以为诸如“str”之类的本机数据类型执行此操作' 和 'int'。 是python 2.x还是3.x? 我目前在我的机器上使用 3.5.2。 【参考方案1】:

一般来说,如果不恢复到 C 级 API,则无法修改内置类型的属性(请参阅 here)。但是,您可以对内置类型进行子类化,并对新类型执行您想要的操作。对于您特别提出的问题(基于添加字符串),您将修改__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

【讨论】:

谢谢。为什么我们不允许更改内置类型的成员属性,是否有任何 Pythonic 原因? 这可能会导致一些太奇怪的事情:你的程序会出现故障,你不知道为什么,因为字符串的__str__ 形式可能意味着一件疯狂的事情,而调试器将无法工作因为整数加法意味着其他一些疯狂的事情。【参考方案2】:

如上所述,您不能(除非您准备构建自己的 Python 实现)。也就是说,如果在代码中遇到'1'+1,您将无法更改其处理方式。但是您可以随意使用内置 函数

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

这只不过是一流函数令人敬畏的一个启发性的例子,你。您所做的任何更改都保留在您正在进行的命名空间中。考虑一下:

>>> 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'
>>> 

您正在使用您在str 中输入的任何内容,在本例中为int。但是input() 知道得更好,并退回到内置函数。闭包可能有一些奇怪的技巧会使其引用您的实现,但我找不到它。顺便说一句,原来的str__builtins__.str,如果你需要它。

在内置方法上使用相同的技巧是行不通的:

>>> 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'

【讨论】:

以上是关于是否可以重载本机数据类型的运算符?的主要内容,如果未能解决你的问题,请参考以下文章

如果编程语言具有数据类型但没有运算符重载,它仍然可以称为“类型化”吗? [关闭]

C++类和对象--运算符重载

c ++:是不是可以在派生类中定义重载运算符,这将工作objs基类类型

操作符重载operator

为新文件类型重载 >> 运算符的优雅方法是啥?

C++运算符重载