根据我在C
++课堂上的记忆,这位教授说运算符重载是很酷的,但是由于要花很多时间才能涵盖所有最终情况(例如,重载时,+
您可能还想重载++
和+=
,并且请确保只处理最终情况,例如向其自身添加对象等),仅应在此功能会对代码产生重大影响的情况下(例如在数学应用程序中重载矩阵类的运算符)考虑使用它。
同样适用于python吗?您是否建议在python中重写操作符行为?您能给我什么经验法则?
当您创建属于现有“抽象基类”(ABC)的新类时,运算符重载最有用-
实际上,标准库模块集合中的许多ABC都依赖于某些特殊方法(和特殊方法)的存在。方法(一种名称以双下划线AKA“
dunders”开头和结尾)正是您在Python中执行运算符重载的方式)。这提供了良好的入门指导。
例如,一个Container
类 必须 重写特殊方法__contains__
,即成员资格检查运算符item in container
(例如,if item in container:
-不要与依赖于!-的for
语句混淆)。同样,必须重写,一个必须重写,一个或一个必须重写,等等。(此外,ABC可以为您的班级提供混合功能-
例如,同时提供这两种功能,并可以在您提供的替代项的基础上提供,从而自动将您的班级设置为a )。for item in container:``__iter__``Hashable``__hash__``Sized``__len__``Sequence``Mapping``__getitem__``Sequence``Mapping``__contains__``__getitem__``Container
除了之外collections
,大多数情况下,如果您的新类“是数字”,您将要覆盖特殊方法(即,提供操作符重载)。还存在其他特殊情况,但是可以抵制重载运算符“仅出于冷静”的诱惑,而没有“正常”含义的语义联系,就像C
++的流为<<
和>>
和Python字符串所做的一样(2.*
幸运的是,在Python中不再存在3.*
;-)做到了%
—当这样的运算符不再意味着“移位”或“除法余数”时,您只会引起混乱。语言的标准库可以摆脱它(尽管不应该;-),但是除非您的库像该语言的标准库一样普及,否则混淆会很麻烦!-)
问题内容: 是否可以在Python中重载运算符?如果是这样,可以定义新的运算符,例如和吗? 问题答案: 正如其他答案所提到的,您确实可以重载运算符(通过在正在编写的类中定义特殊方法,即名称以两个下划线开头和结尾的方法)。所有的细节都在这里。 要完成对您问题的回答:您不能定义新的运算符;但是它不是一个新的运算符,它是一个现有的运算符,并且通过在类中定义method来使其过载。 作为历史记录,这在C
问题内容: 我最近了解了python中的运算符重载,并且我想知道以下情况是否可能。 考虑以下假设/人为的类。 我知道上面写的方式,我可以做这样的事情 这些将按预期工作。我也知道目前的书写方式我无法做到这一点 有没有办法解决?我知道这个例子是人为设计的,但是我有一个应用程序,如果当我进行运算符重载时,为它定义运算符的类可以出现在运算符的右侧,它将非常有用。这可能在python中吗? 问题答案: 是。
问题内容: 如何在Python中模拟赋值运算符重载?例如… 除了执行self.name.value = name之外,还可以如何模拟赋值运算符的重载,以便在执行self.name = myname时将myname分配给self.name.value? 问题答案: 我最终创建了一个名为ModelMeta的Model元类,该元类注册了类型化的属性。 参见http://github.com/espeed
前面章节介绍了 Python 中的各个序列类型,每个类型都有其独特的操作方法,例如列表类型支持直接做加法操作实现添加元素的功能,字符串类型支持直接做加法实现字符串的拼接功能,也就是说,同样的运算符对于不同序列类型的意义是不一样的,这是怎么做到的呢? 其实在 Python 内部,每种序列类型都是 Python 的一个类,例如列表是 list 类,字典是 dict 类等,这些序列类的内部使用了一个叫作
问题内容: 请告诉我Java是否可以重载运算符?如果可以在Java中的任何地方使用它,请告诉我。 问题答案: 不,Java不支持用户定义的运算符重载。Java唯一接近“自定义”运算符重载的方面是对字符串+的处理,这将导致常量的编译时串联或使用StringBuilder / StringBuffer的执行时串联。但是,您无法定义自己的操作符,它们的操作方式相同。 对于确实支持运算符重载的类Java(
问题内容: 我似乎找不到在JavaScript中重载[]运算符的方法。外面有人知道吗? 我在想… 还是我没有看正确的东西。 问题答案: 您可以使用ES6代理(在所有现代浏览器中都可用)进行此操作