前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python和Scala的操作符

Python和Scala的操作符

作者头像
哒呵呵
发布2018-08-06 14:19:47
4060
发布2018-08-06 14:19:47
举报
文章被收录于专栏:鸿的学习笔记鸿的学习笔记

在聊完类和对象之后,我们要理解一件事,无论是在Scala还是Python,每一个值都是对象,在某种程度上来说,这两门语言都是更加纯粹的面向对象的语言。两者也都支持函数是一等对象,区别在于Python并不认为自己是函数式编程语言,而Scala处处都在鼓励使用不可变的数据结构。今天要聊的是操作符,我们可以看到在Scala和Python里如何给一个自定义对象加上操作符。

首先从概念的开始: Scala的操作符并不算是重载,而是“操作符即方法”,在Scala里的操作符可以作为方法的名字,如前面的文章提到的,1+2实际上是1.+(2)的语法糖,之前的我们可能还不好理解,现在我们可以这么理解,1代表着一个Int类的实例,有个方法被命名为+,接受一个参数,返回Int结果。+符号这种方法,在Scala里被称为操作符表示法,这个表示法使我们可以不必用.号去调用对象的方法。+号可以理解为一种二元操作符,接受两个操作元,一个在左一个在右,还有一种叫做是一元操作符,用来表示正数和负数,例如-,+,!,~符号,不过不同于+符号直接使用+作为符号名,一元操作符使用'unary_'加上操作符表示。除了运算符外,还有一种符号叫做逻辑操作,例如<,>,>=返回比较的结果的Boolean值。

代码语言:javascript
复制
scala> 2.unary_-
res0: Int = -2

回过头来看看Python的操作符重载,这个重载是名副其实的重载,Python通过使用操作符重载使得用户定义的对象可以使用二元运算符和一元运算符。不过Python为了防止运算符重载的乱用,加了一些限制:例如不能重载内置类型的运算符(也就是说不能通过继承重载),不能新建运算符。Python重载+使用的是__add__方法,我们的1+1也实际上使用的也是__add__方法。只要用户在自定义的类里定义了__add__,+实际上就会调用用户定义的__add__方法。再来看一元操作符,例如-,也就可以是用__ne__来实现负数。

代码语言:javascript
复制
i = 1
i.__add__(1)
Out[2]: 2

总的来说,原则就一个:运算符的方法始终返回一个新的对象,也就是说,要创建并返回一个适合类型的新实例。

例子: 概念相对比较枯燥,还是从例子上来说明吧。我们可以简单的实现一个二元向量类做为示例(在Scala和Python都有更好的库去实现一个向量,例子中的向量仅仅只是为了展示如何重载运算符,而且在Python的实现也没有加上类型检查)

0.更好的显示 Scala:

代码语言:javascript
复制
class Vector(x:Int, y:Int){
    override def toString = s"Vector($x,$y)"
}
代码语言:javascript
复制
scala> val a = new Vector(1,2)
a: Vector = Vector(1,2)

Python:

代码语言:javascript
复制
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return 'Vector(%s, %s)'%(self.x, self.y)
代码语言:javascript
复制
Vector(1,2)
Out[4]: Vector(1, 2)        

我们看出来返回的结果是Vector(1,2), 具体的细节后面再说。

1.重载一元操作符 Scala:

代码语言:javascript
复制
class Vector(x:Int, y:Int){
    override def toString = s"Vector($x,$y)"
    val x1:Int = x
    val y1:Int = y
    def unary_-():Vector = new Vector(-x1, -y1)
    def unary_+():Vector = new Vector(x1,y1)
}
代码语言:javascript
复制
scala> val a = new Vector(1,2)
a: Vector = Vector(1,2)

scala> -a
res2: Vector = Vector(-1,-2)

scala> +a
res3: Vector = Vector(1,2)

Python:

代码语言:javascript
复制
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return 'Vector(%s, %s)'%(self.x, self.y)

    def __neg__(self):
        return Vector(-self.x, -self.y)

    def __pos__(self):
        return Vector(self.x, self.y)
代码语言:javascript
复制
a = Vector(1,2)
-a
Out[8]: Vector(-1, -2)
+a
Out[9]: Vector(1, 2)        

Scala里我们要注意x,y重新赋值给了x1,y1,这个是因为参数x,y是属于类的的作用域里面的,在后面实现二元操作符时,我们需要传入一个Vector的实例,而x,y在这个时候是不能使用的。这时候要访问x,y,必须要通过字段来访问。

2.二元操作符: Scala:

代码语言:javascript
复制
class Vector(x:Int, y:Int){
    ...
    def +(that:Vector):Vector = new Vector(x + that.x1, y + that.y1)
    def *(that:Vector):Vector = new Vector(x * that.x1, y * that.y1)
}
代码语言:javascript
复制
scala> val a = new Vector(1,2)
a: Vector = Vector(1,2)

scala> val b = new Vector(2,2)
b: Vector = Vector(2,2)

scala> a+b
res4: Vector = Vector(3,4)

scala> a*b
res5: Vector = Vector(2,4)

Python:

代码语言:javascript
复制
class Vector:
    ...  
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)

    def __mul__(self, other):
        return Vector(self.x * other.x, self.y * other.y)
代码语言:javascript
复制
a = Vector(1,2)

b = Vector(2,2)

a+b
Out[19]: Vector(3, 4)

a*b
Out[20]: Vector(2, 4)

3.比较运算符 Scala:

代码语言:javascript
复制
class Vector(x:Int, y:Int){
    ...
    def ==(that:Vector):Boolean = x == that.x1 & y == that.y1
    def !=(that:Vector):Boolean = {
      val result = that == new Vector(x,y)
      !result
    }
   }
代码语言:javascript
复制
scala> a == b
res7: Boolean = false

scala> a != b
res8: Boolean = true   

Python:

代码语言:javascript
复制
class Vector:
    ...
    def __eq__(self, other):
        return (self.x == other.x) and (self.y == other.y)

    def __ne__(self, other):
        eq_result = self == other
        return not eq_result 
代码语言:javascript
复制
a == b
Out[21]: False

a != b
Out[22]: True
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-03-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档