是否可以重载本机数据类型的运算符?
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__()
方法来实现这一点。
但是,出于好奇,我想知道:是否可以重载int
和str
的类定义中的+ 运算符,以便__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'
【讨论】:
以上是关于是否可以重载本机数据类型的运算符?的主要内容,如果未能解决你的问题,请参考以下文章
如果编程语言具有数据类型但没有运算符重载,它仍然可以称为“类型化”吗? [关闭]