python次方运算_neg__python 魔术方法1 运算符重载

python中存在一些特殊的方法,这些方法通常采用格式:__method__()。这些方法会在特定的情况下自动调用。例如:__new__()、__init__()、__del__() 等生命周期方法。正是这些特殊方法,构建了python的语言风格。特殊方法有很多,比如下面列出来的这些,我们按照类别研究其中的一部分。其他的等到真的用到的再往上加吧。

python中的魔术方法

我们先来看看这些特殊方法有什么用,它作了什么简化,一般在实际情况下我们什么时候才会使用到这些方法。

假设有一个表示在线订单的类,具有购物车 (列表) 和顾客 (代表顾客的str或其他类的实例)两种数据。

在这种情况下,要获得购物车列表的长度是很自然的。新接触 Python 的人可能会选择在他们的类中实现一个叫get_cart_len()的方法来执行此项。但是,你也可以重载内置函数len(),以便在给定对象时返回购物车列表的长度。

在另一种情况下, 我们可能需要添加一些东西到购物车。再次,新接触 Python 的人会想到实现一个append_to_cart()方法,以添加东西到购物车列表。但是你也可以配置运算符+,用它来将新内容添加到购物车中。

Python 使用特殊的方法来做这些。这些特殊方法具有命名约定,其中名称以两个下划线开头, 后跟一个标识符, 并以另一对下划线结尾。(就是我们说的魔术方法啦)

本质上, 每个内置函数或运算符都有一个与之对应的特殊方法。例如,对应于 len()有__len__(),对应于运算符 + 有__add__()。

默认情况下, 大多数内置函数和运算符都不能与自定义类的对象一起使用。必须在类定义中添加相应的特殊方法,才能使对象与内置和运算符兼容。这就是我们接下来要讨论的 python 运算符重载。

执行此操作时,与其关联的函数或运算符的行为将根据方法中定义的方式进行更改。

在说运算符重载之前,我们来看一下魔术方法的特点:(敲黑板儿)

特殊方法定义在class中

不需要直接调用

python的某些函数或操作符会调用相应的特殊方法

运算符重载

目的:让自定义的类生成的对象(实例)能够使用运算符进行操作。依据运算数据的不同,为运算符定义不同的行为。

作用(好处):

让自定义的实例像内建对象一样进行运算符操作,令用户定义的对象能够使用中缀运算符(如 + 和 | )或一元运算符(如 - 和 ~ )等运算符。

让程序简洁易读;

对自定义对象将运算符赋予新的规则。

我们知道,数据类型 = 数据结构 + 运算 ,有了运算符重载意味着我们可以定义自己的数据类型了。

为了做好灵活性、可用性和安全性方面的平衡,Python对运算符重载施加了一些限制:

不能重载内置类型的运算符;

不能新建运算符,只能重载现有运算符;

某些运算符不能重载,如is、and、or和not(不过位运算符&、| 和 ~可以)。

下面我们来看一个例子:二维向量类的加法。(这个例子太经典啦哈哈哈)

假设有Vector2D类代表一个二维向量。我们知道Vector2D(3,4) + Vector2D(1,1) = Vector2D(4,5),我们通过重载魔术方法__add__来实现这一功能。

class Vector2D:

def __init__(self, x, y):

self.x = x

self.y = y

def __add__(self, other):

x = self.x + other.x

y = self.y +other.y

return Vector2D(x, y)

def __str__(self):

return "Vector2D(x={}, y={})".format(self.x, self.y)

v1 = Vector2D(1, 2)

v2 = Vector2D(3, 4)

v3 = v1 + v2

print(v3)

Vector2D(x=4, y=6)

结果是正确的,我们并没有调用__add__而是直接使用 + 就可以啦,还记得之前我们说过的魔术方法的特点吗?

当我们在重载双目运算符的时候,会多传入一个参数other。

在上面的例子中我们还重载了一个特殊方法__str__, 我们下面会介绍这个方法, 这个方法通过 print() 函数调用。

接下来我们在重载一些其他的运算:

from math import hypot,sqrt

class Vector:

def __init__(self, x, y):

self.x = x

self.y = y

#__str__方法,会在打印变量时,自动调用

def __str__(self):

return 'Vector(%r,%r)' %(self.x, self.y)

#__abs__函数会在调用abs()函数时,自动调用

def __abs__(self):

#hypot(x,y) 返回欧几里得范数 sqrt(x*x + y*y)

return hypot(self.x, self.y)

#__bool__函数会在调用bool()函数时,自动调用

def __bool__(self):

return bool(abs(self))

# 执行a + b时,自动调用

def __add__(self, other):

x = self.x + other.x

y = self.y + other.y

return Vector(x,y)

# 执行a+=b时,自动调用

def __iadd__(self, other):

return self + other

# 执a * b的时候,会自动调用

def __mul__(self, scalar):

return Vector(self.x * scalar,self.y * scalar)

# 求-a时,自动调用

def __neg__(self):

return Vector(-self.x,-self.y)

def __matmul__():

pass

v1 = Vector(2,4)

v2 = Vector(2,1)

print(v1 + v2)

v = Vector(3,4)

print(abs(v))

print(v * 3)

print(abs(v * 3))

print(-v)

v1 += v2

print(v1)

Vector(4,5)

5.0

Vector(9,12)

15.0

Vector(-3,-4)

Vector(4,5)

在上面我们实现了自加操作,(+=)实际上因为我们实现了 + 操作,解释器会自动实现这个方法。

值得注意的是反向操作,如果你了解 Matlab 一定知道Matlab有左除与右除。python也有类似的用法。我们以加法为例:辨析 __add__()与__radd__()的不同.

先看一个例子:

class A:

def __add__(self, other):

print('A add')

def __radd__(self, other):

print('B add')

class B:

pass

if __name__ == "__main__":

a = A()

b = B()

a + b

b + a

A add

B add

在这个例子中,在b + a 时b没有实现加法操作,那么解释器就调用了,a 的反向方法。

执行a + b 的流程如下:

如果a有__add__方法,而且返回值不是NotImplemented,调用a.__add__(b),然后返回结果。

如果a没有__add__方法,或者调用__add__方法返回NotImplemented,检查b有没有__radd__方法,如果有,而且没有返回NotImplemented,调用b.__radd__(a),然后返回结果。

如果b没有__radd__方法,或者调用__radd__方法返回NotImplemented,抛出TypeError,并在错误消息中指明操作数类型不支持。

常见的运算符重载方法

中缀运算符

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502088.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

resnet50网络结构_AAAI2020 | 利用网络结构关系加速NAS+Layer

这是我在海康威视研究院实习的工作,被AAAI-2020接收为Spotlight。论文地址:http://xxx.itp.ac.cn/pdf/2002.12580v1引子上一个阶段的网络结构搜索(NAS)研究,主要在两个方面。1)各类搜索方法,从强化学习、进化算法等到梯度下降&…

python 去除nan inf_Python实现半自动评分卡建模(附代码)

作者:Summer Memories个人公众号:风控汪的数据分析之路知乎专栏:小鑫的数据分析笔记这次分享一个自己写的python脚本,可以实现半自动化的评分卡建模。运行脚本时需要input已经预处理好的训练集和测试集数据,所以建模前…

国嵌c语言深度,国嵌C语言3部全

课程目录:国嵌 C语言深度剖析班:1课-基本数据类型分析2 auto,register,static分析3 if,switch,do,while,for分析4 goto,void,extern,sizeof分析5 const和volatile分析6 struct和union分析7课-enum和typedef分析8 注释符号9 接续符和转义符10 单引号和双引…

linux如何判断网线插入_“Linux”中如何判断哪个网卡连接网线?

展开全部【解决方法】1、ifconfig查看现在使用的网e68a84e8a2ad3231313335323631343130323136353331333365633935卡。2、ethtool命令查看网卡的具体信息,如eth0是连接状态,则正常使用。2、在ifconfig中可以看到有eth2这个网卡,但不知道是否连线&#xff…

单调有界定理适用于函数吗_《实变函数》——论有界变差函数

一日不见如隔三秋,本人觉得有界变差函数是实变函数中最容易理解且和高等数学联系最紧密的一个概念,其在概率论中也有非常广泛的应用,也和勒贝格空间有着千丝万缕的联系。什么叫有界变差函数?若在区间(a,b)中&#xff0…

msp430 c语言开发环境,如何使用C语言来编写MSP430的高质量代码

微处理器一般用于特定环境和特定用途,出于成本、功耗和体积的考虑,一般都要求尽量节省使用资源,并且,由于微处理器硬件一般都不支持有符号数、浮点数的运算,且运算位有限,因此,分配变量时必须仔细。另外要说…

oracle 增量设为3 循环_Oracle 差异性增量 和 累计增量 原理(转)

RMAN一个强大的功能是支持增量备份,增量备份中心思想就是减少备份的数据量,我们不需要在从头开始备份了,只需要备份自上次已备份之后的数据块即可。Oracle 9i 共有五种级别 0 1 2 3 4,0级最高-4级最低,0级是1级的基础以…

springboot redis 断线重连_Redis(9)——史上最强【集群】入门实践教程

一、Redis 集群概述Redis 主从复制到 目前 为止,我们所学习的 Redis 都是 单机版 的,这也就意味着一旦我们所依赖的 Redis 服务宕机了,我们的主流程也会受到一定的影响,这当然是我们不能够接受的。所以一开始我们的想法是&#xf…

智能指针的释放_看完这篇,别再说不会智能指针了

C智能指针一、智能指针的作用上一篇介绍了内存池的原理和实现,详情请见内存池设计与实现;内存池可以帮助我们有效的对内存进行管理,智能指针可以很方便的管理指针,避免出现内存泄漏;智能指针的作用智能指针的作用&…

c语言输出后面空格,新人提问:如何将输出时每行最后一个空格删除

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼如何将每行最后一个空格删除&#xff0c;使矩阵只有数字间有空格&#xff0c;没有多余空格&#xff1f;#include#includeint main(){int i,j,k,m,n,x,h,y;int a[15][15]{0};while(scanf("%d",&i)){k1;for(n1;n<i;…

pandas 日期比较大小_pandas处理日期时间,按照时间筛选

pandas有着强大的日期数据处理功能&#xff0c;本期我们来了解下pandas处理日期数据的一些基本功能&#xff0c;主要包括以下三个方面&#xff1a;按日期筛选数据按日期显示数据按日期统计数据运行环境为 windows系统&#xff0c;64位&#xff0c;python3.5。1 读取并整理数据首…

python中符号输入_Python基础(输入、运算符)

输入 1. python2版本中 1.1 使用 raw_input()函数&#xff0c; 看如下示例: password raw_input("请输入密码:") print &#xff08;您刚刚输入的密码是:%s, % password&#xff09; 运行结果:注意: raw_input()的小括号中放入的是&#xff0c;提示信息&#xff0c;…

c语言课程教学改革,C语言课程教学改革和实践.doc

C语言课程教学改革和实践C语言课程教学改革和实践程序设计课程在计算机科学(Computer Science&#xff0c; CS)专业新生的教学中起着相当基础的作用&#xff0c;CS专业包括计算机科学与技术、软件工程和网络工程。尽管近年来涌现了很多新的程序设计语言&#xff0c;如java&…

audio接线图解_图文:主板跳线(排线)连接技巧HD AUDIO连线接法

作为一名新手&#xff0c;要真正从头组装好自己的电脑并不容易&#xff0c;也许你知道CPU应该插哪儿&#xff0c;内存应该插哪儿&#xff0c;但遇到一排排复杂跳线的时候&#xff0c;很多新手都不知道如何下手。钥匙开机其实并不神秘还记不记得你次见到装电脑的时候&#xff0c…

code blocks c语言,Code Blocks安装与使用图文教程(使用Code::Blocks编写C语言程序)...

CodeBlocks 完全支持单个源文件的编译&#xff0c;如果你的程序只有一个源文件(初学者基本上都是在单个源文件下编写代码)&#xff0c;那么不用创建项目&#xff0c;直接运行即可&#xff1b;如果有多个源文件&#xff0c;才需要创建项目。1) 新建源文件打开 CodeBlocks &#…

python链表实现栈_python实现链表队列栈

#!/usr/bin/python # -*- coding: utf-8 -*- #便于测试 data 使用数字 class Node(object): def __init__(self,data): self.data data self.next None self.prev None class List(object): def __init__(self): self.next self self.prev self self.size 0 # 是否为空 d…

python except用法和作用_Python面试题(部分附带面试标准答案) 建议收藏

1、请尽可能列举python列表的成员方法&#xff0c;并给出一下列表操作的答案&#xff1a;&#xff08;1&#xff09; a[1, 2, 3, 4, 5], a[::2]?, a[-2:] ?&#xff08;2&#xff09; 一行代码实现对列表a中的偶数位置的元素进行加3后求和&#xff1f;&#xff08;3&#xf…

c语言简单的24点游戏,C语言解24点游戏程序

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼前几天在微博上看到24点的游戏&#xff0c;6 6 610。算了很久是在算不出来&#xff0c;最后我想我何不写一个小程序解决它&#xff1f;说做就做&#xff0c;我刚开始的想法很简单&#xff0c;就是列举4个数的所有可能的表达式组合&…

chrome vue插件_VS Code 前端常用插件推荐

⊕.vscode安装插件只需要点击图片所示按钮&#xff0c;即可进入拓展&#xff0c;在搜索框中输入插件名点击安装后&#xff0c;等待安装好即可点击重新加载重启vscode使得插件生效。Ξ.当你不需要某个插件时只需要进入扩展&#xff0c;点击对应插件右下角的齿轮按钮即可选择禁用…

ubantu获取信息_Ubuntu 下查看CPU 信息命令

查看当前操作系统内核信息uname -aLinux redcat 2.6.31-20-generic #58-Ubuntu SMP Fri Mar 12 05:23:09 UTC 2010 i686 GNU/Linux查看当前操作系统发行版信息cat /etc/issueUbuntu 9.10 /n /l查看cpu型号cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c2 Intel(R) Cor…