侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python运算符重载详解及实例代码

Python  /  管理员 发布于 7年前   185

Python运算符重载

      Python语言提供了运算符重载功能,增强了语言的灵活性,这一点与C++有点类似又有些不同。鉴于它的特殊性,今天就来讨论一下Python运算符重载。

      Python语言本身提供了很多魔法方法,它的运算符重载就是通过重写这些Python内置魔法方法实现的。这些魔法方法都是以双下划线开头和结尾的,类似于__X__的形式,python通过这种特殊的命名方式来拦截操作符,以实现重载。当Python的内置操作运用于类对象时,Python会去搜索并调用对象中指定的方法完成操作。

       类可以重载加减运算、打印、函数调用、索引等内置运算,运算符重载使我们的对象的行为与内置对象的一样。Python在调用操作符时会自动调用这样的方法,例如,如果类实现了__add__方法,当类的对象出现在+运算符中时会调用这个方法。

常见运算符重载方法

方法名

重载说明

运算符调用方式

__init__

构造函数

对象创建: X = Class(args)

__del__

析构函数

X对象收回

__add__/__sub__

加减运算

 X+Y, X+=Y/X-Y, X-=Y

__or__

运算符|

X|Y, X|=Y

_repr__/__str__

打印/转换

print(X)、repr(X)/str(X)

__call__

函数调用

X(*args, **kwargs)

__getattr__

属性引用

X.undefined

__setattr__

属性赋值

X.any=value

__delattr__

属性删除

del X.any

__getattribute__

属性获取

X.any

__getitem__

索引运算

X[key],X[i:j]

__setitem__

索引赋值

X[key],X[i:j]=sequence

__delitem__

索引和分片删除

del X[key],del X[i:j]

__len__

长度

len(X)

__bool__

布尔测试

bool(X)

__lt__, __gt__, 

__le__, __ge__, 

__eq__, __ne__

特定的比较

依次为X<Y,X>Y,X<=Y,X>=Y, 

X==Y,X!=Y 

注释:(lt: less than, gt: greater than, 

  le: less equal, ge: greater equal, 

  eq: equal, ne: not equal 

)

__radd__

右侧加法

other+X

__iadd__

实地(增强的)加法

X+=Y(or else __add__)

__iter__, __next__

迭代

I=iter(X), next()

__contains__

成员关系测试

item in X(X为任何可迭代对象)

__index__

整数值

hex(X), bin(X),  oct(X)

__enter__, __exit__

环境管理器

with obj as var:

__get__, __set__, 

__delete__

描述符属性

X.attr, X.attr=value, del X.attr

__new__

创建

在__init__之前创建对象

   下面对常用的运算符方法的使用进行一下介绍。

构造函数和析构函数:__init__和__del__

       它们的主要作用是进行对象的创建和回收,当实例创建时,就会调用__init__构造方法。当实例对象被收回时,析构函数__del__会自动执行。

>>> class Human(): ...   def __init__(self, n): ...     self.name = n ...       print("__init__ ",self.name) ...   def __del__(self): ...     print("__del__") ...  >>> h = Human('Tim') __init__ Tim >>> h = 'a' __del__ 

加减运算:__add__和__sub__

       重载这两个方法就可以在普通的对象上添加+-运算符操作。下面的代码演示了如何使用+-运算符,如果将代码中的__sub__方法去掉,再调用减号运算符就会出错。

>>> class Computation(): ...   def __init__(self,value): ...     self.value = value ...   def __add__(self,other): ...     return self.value + other ...   def __sub__(self,other): ...     return self.value - other ...  >>> c = Computation(5) >>> c + 5 10 >>> c - 3 2 

对象的字符串表达形式:__repr__和__str__

       这两个方法都是用来表示对象的字符串表达形式:print()、str()方法会调用到__str__方法,print()、str()和repr()方法会调用__repr__方法。从下面的例子可以看出,当两个方法同时定义时,Python会优先搜索并调用__str__方法。

>>> class Str(object): ...   def __str__(self): ...     return "__str__ called"   ...   def __repr__(self): ...     return "__repr__ called" ...  >>> s = Str() >>> print(s) __str__ called >>> repr(s) '__repr__ called' >>> str(s) '__str__ called' 

索引取值和赋值:__getitem__, __setitem__

       通过实现这两个方法,可以通过诸如 X[i] 的形式对对象进行取值和赋值,还可以对对象使用切片操作。

>>> class Indexer:   data = [1,2,3,4,5,6]   def __getitem__(self,index):     return self.data[index]   def __setitem__(self,k,v):     self.data[k] = v     print(self.data) >>> i = Indexer() >>> i[0] 1 >>> i[1:4] [2, 3, 4] >>> i[0]=10 [10, 2, 3, 4, 5, 6] 

设置和访问属性:__getattr__、__setattr__

       我们可以通过重载__getattr__和__setattr__来拦截对对象成员的访问。__getattr__在访问对象中不存在的成员时会自动调用。__setattr__方法用于在初始化对象成员的时候调用,即在设置__dict__的item时就会调用__setattr__方法。具体例子如下:

class A():   def __init__(self,ax,bx):     self.a = ax     self.b = bx   def f(self):     print (self.__dict__)   def __getattr__(self,name):     print ("__getattr__")   def __setattr__(self,name,value):     print ("__setattr__")     self.__dict__[name] = value  a = A(1,2) a.f() a.x a.x = 3 a.f() 

     上面代码的运行结果如下,从结果可以看出,访问不存在的变量x时会调用__getattr__方法;当__init__被调用的时候,赋值运算也会调用__setattr__方法。

__setattr__ __setattr__ {'a': 1, 'b': 2} __getattr__ __setattr__ {'a': 1, 'x': 3, 'b': 2} 

迭代器对象: __iter__,  __next__

       Python中的迭代,可以直接通过重载__getitem__方法来实现,看下面的例子。

>>> class Indexer: ...   data = [1,2,3,4,5,6] ...   def __getitem__(self,index): ...       return self.data[index] ...  >>> x = Indexer() >>> for item in x: ...   print(item) ...  1 2 3 4 5 6 

      通过上面的方法是可以实现迭代,但并不是最好的方式。Python的迭代操作会优先尝试调用__iter__方法,再尝试__getitem__。迭代环境是通过iter去尝试寻找__iter__方法来实现,而这种方法返回一个迭代器对象。如果这个方法已经提供,Python会重复调用迭代器对象的next()方法,直到发生StopIteration异常。如果没有找到__iter__,Python才会尝试使用__getitem__机制。下面看一下迭代器的例子。

class Next(object):   def __init__(self, data=1):     self.data = data   def __iter__(self):     return self   def __next__(self):     print("__next__ called")     if self.data > 5:       raise StopIteration     else:       self.data += 1       return self.data for i in Next(3):   print(i) print("-----------") n = Next(3) i = iter(n) while True:   try:     print(next(i))   except Exception as e:     break 

   程序的运行结果如下:

__next__ called 4 __next__ called 5 __next__ called 6 __next__ called ----------- __next__ called 4 __next__ called 5 __next__ called 6 __next__ called 

    可见实现了__iter__和__next__方法后,可以通过for in的方式迭代遍历对象,也可以通过iter()和next()方法迭代遍历对象。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


  • 上一条:
    Python搭建HTTP服务器和FTP服务器
    下一条:
    利用Python中的pandas库对cdn日志进行分析详解
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go语言中实现字符串可逆性压缩及解压缩功能(0个评论)
    • 使用go + gin + jwt + qrcode实现网站生成登录二维码在app中扫码登录功能(0个评论)
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客