一、基础知识

定义:当类中提供了某个特殊名称的方法,在该类的实例出现在它们相关的表达式时,Python自动调用它们
特性:
1、运算符重载让类拦截常规的Python运算。
2、类可重载所有Python表达式运算符。
3、类可重载打印,函数调用,属性点号运算等内置运算
4、重载使类实例的行为像内置类型
5、重载是通过提供特殊名称的类方法来实现的

二、字典索引和分片:_getitem_,_setitem_,_delitem_

如果在类中定义了(或者继承了)的话,则对于实例中的索引运算,会自动调用__getitem__,__setitem__,__delitem__三个方法。当实例X出现X[i]这样的索引运算时,Python会调用这个实例继承的__getitem__,__setitem__,__delitem__方法(如果有的话)
class Foo:
def __init__(self,name):
self.name=name
def __getitem__(self, item):
return self.__dict__[item]
def __setitem__(self, key, value):
self.__dict__[key]=value
def __delitem__(self, key):
del self.__dict__[key] F=Foo('egon') #实例化
print(F['name']) #打印,以字典索引的方式,会找到__getitem__方法下的代码,‘name’传递给第二个参数
F['age']=18 #赋值操作,直接传递给__setitem__方法
print(F.__dict__) #打印F的命名空间
del F['age'] #del会调用__delitem__方法,删除‘age’
print(F.__dict__) 打印结果为:
egon
{'name': 'egon', 'age': 18}
{'name': 'egon'}

三、_slots_

__slots__:实例化的对象将没有名称空间,都保存在类的名称空间,而且只能设置指定的属性,例如下面的例子,每个实例只能设置x,y,z三个属性

class People:
__slots__=['x','y','z'] p=People
p.x=1
p.y=2
p.z=3
print(People.__dict__)
p.e=4 #这个将会报错

四、迭代器对象:_iter_,_next_

python 中所有的迭代环境都会先尝试__iter__方法,再尝试__getitem__,也就是说,只有对象在不支持迭代的情况下,才会尝试索引的方式运算。
Python中,迭代环境是通过调用内置函数iter去尝试寻找__iter__方法来实现的,而这种方法返回一个迭代器对象,如果已经提供了,Python就会重复调用这个迭代器对象的next方法,知道发生了StopIteration异常
class Range:
def __init__(self,start,end,long): #构造函数,定义三个元素,start,end,long
self.start=start
self.end=end
self.long=long
def __iter__(self): #__iter__:生成迭代器对象self
return self #返回这个迭代器本身
def __next__(self): #__next__:一个一个返回迭代器内的值
if self.start>=self.end:
raise StopIteration
n=self.start
self.start+=self.long
return n r=Range(1,10,2) #实例化对象r,
for i in r: #r会首先调用__iter__方法,把自己转换为迭代器
print(i)

五、实现上下文管理:with/as,_enter_,_exit_

with open('a.txt') as f:#with代码块后会自定关闭文件,无论是否发生异常,一下是with的工作方式:
1、计算表达式,所得到的对象称为环境管理器,他必须有__enter__,__exit__方法。
2、环境管理器的__enter__方法会被调用。如果as字句存在,器返回值会赋值给as字句中的变量,否则直接丢弃。
3、代码块中嵌套的代码会执行。
4、如果with代码块引发异常,__exit__(type,value,traceback)方法就会调用(带有异常细节)
5、如果with代码块没有引发异常,__exit__方法依然会被调用,其type,value,traceback参数都会以none传递
import time
class Open:
def __init__(self,filepath,mode='r',encoding='utf8'):
self.filepath=filepath
self.mode=mode
self.encoding=encoding
self.x=open(filepath,mode=mode,encoding=encoding) def write(self,line):
t=time.strftime('%Y-%m-%d %X')
self.x.write('%s %s' %(t,line))
def __getattr__(self, item):
return getattr(self.x,item) def __enter__(self):
print("*************")
return self def __exit__(self, exc_type, exc_val, exc_tb):
print('文件关闭')
self.x.close() with Open('a.txt','w') as f: #出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量
f.write("abc") #调用自己定义的write方法,把‘abc’ 写入到a.txt文件
print('==============') #这一行代码执行完毕后,会触发__exit__方法,关闭文件
print("继续执行代码") #代码执行如下
*************
==============
文件关闭
继续执行代码

六、_call_:python会为实例用函数调用的表达式运行__call__方法,这样就可以让类实例的外观看起来像是函数

class callee:
def __call__(self, *args, **kwargs):
print('call:',args,kwargs)
C=callee()
C(1,2,3) #实例加()后,会调用__call__方法
C(1,2,3,X=4,Y=5) #打印结果如下
call: (1, 2, 3) {}
call: (1, 2, 3) {'X': 4, 'Y': 5}

七、_del_:析构函数

每当实例产生时,就对调用__init__构造函数,没当实例空间被收回时,就会调用__del__析构函数。吃方法一般不需定义,python 有自己的内存回收机制
import time
class Open:
def __init__(self,filepath,mode='r',encoding='utf8'):
self.filepath=filepath
self.mode=mode
self.encoding=encoding
self.x=open(filepath,mode=mode,encoding=encoding)
def __del__(self):
print('del')
self.x.close()
f=Open('a.txt','w') del f

python运算符重载(二)的更多相关文章

  1. python运算符重载

    python运算符重载就是在解释器使用对象内置操作前,拦截该操作,使用自己写的重载方法. 重载方法:__init__为构造函数,__sub__为减法表达式 class Number: def __in ...

  2. C++ 运算符重载二(一元运算符重载)

    //一元运算符重载 #include<iostream> using namespace std; class Point { public: Point(int x,int y){ th ...

  3. 【C/C++开发】运算符重载二

    C++中预定义的运算符的操作对象只能是基本数据类型.但实际上,对于许多用户自定义类型(例如类),也需要类似的运算操作.这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够用于特定类 ...

  4. Python 运算符重载

    https://www.cnblogs.com/hotbaby/p/4913363.html

  5. python 的重载

    python 的重载主要包括方法重载和运算符重载.1.python 方法重载: 其他的语言一般对于方法重载的话,主要是根据参数的类型不同或者是数量不同来区分同名的方法.而python则比较特殊,它本身 ...

  6. python类可以截获Python运算符

    类可以截获Python运算符 现在,让我们来看类和模块的第三个主要差别: 运算符重载.简而言之,运算符重载就是让用类写成的对象,可截获并响应用在内置类型上的运算:加法.切片.打印和点号运算等.这只是自 ...

  7. Python 正确重载运算符

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Helvetica } 有些事情让我不安,比如运算符重载.我决定不支持运算符重载,这完全是个人 ...

  8. Python全栈工程师(异常(高级)、运算符重载)

    ParisGabriel              每天坚持手写  一天一篇  决定坚持几年 为了梦想为了信仰    开局一张图 Python人工智能从入门到精通 对象的属性管理函数: getattr ...

  9. [b0018] python 归纳 (四)_运算符重载

    # -*- coding: UTF-8 -*- """ 测试运算符重载 加法 总结: python 运算符表达式其实都是调用 类中方法 __xxx__ + <--- ...

随机推荐

  1. aspnetcore.webapi实践k8s健康探测机制 - kubernetes

    1.浅析k8s两种健康检查机制 Liveness k8s通过liveness来探测微服务的存活性,判断什么时候该重启容器实现自愈.比如访问 Web 服务器时显示 500 内部错误,可能是系统超载,也可 ...

  2. Angular开发实践(一):环境准备及框架搭建

    引言 在工作中引入Angular框架将近一年了,在这一年中不断的踩坑和填坑,当然也学习和积累了很多的知识,包括MVVM框架.前后端分离.前端工程化.SPA优化等等.因此想通过Angular开发实践这系 ...

  3. thinkphp3.2-更改控制器名后找不到相应的表?报1146的错

    用tp在做着自己的小系统的时候,明明在刚才还是能好好地查到表的,在Service用了'D'方法连自己数据库的表,只是更改了自己的控制器名,却报错了... 我就纳闷了,虽然我的控制器和Service用的 ...

  4. React简明学习

    前面的话 React让组件化成为了前端开发的基本思路,比传统思路可以更好的控制前端复杂度,旧的开发方法受到了影响,如分离式的HTML/CSS.非侵入式JS.模板语言.MVC.CSS文件.Bootstr ...

  5. Spring事务管理—aop:pointcut expression解析(转)

    本文转载自: http://hane00.blog.163.com/blog/static/160061522011427473965/ 先来看看这个spring的配置文件的配置: <!-- 事 ...

  6. 使用selenium时提示:ImportError:No module named selenium

    问题分析: 用的是mac系统,已经通过sudo pip install -U selenium安装好了selenium, 但是无论用命令行还是用sublime导入selenium都会提示错误. 于是查 ...

  7. java————面向对象概念

    面向对象 OO:面向对象 OOP:面向对象编程 OOA:面向对象分析 OOD:面向对象设计 面向对象的特征 继承,封装,多态 什么是对象? 对象是存在的具体实体,具有明确定义的特征和行为. 万物皆对象 ...

  8. C语言第四次作业--嵌套循环

    一.PTA实验作业 题目1:打印九九口诀表 1.本题PTA提交列表 2.设计思路 (1)定义三个整形变量n,j,i,n表示任意给定的正整数. (2)输入一个正整数n. (3)令i=1,i<=n, ...

  9. 20162308 实验二《Java面向对象程序设计》实验报告

    20162308 实验二<Java面向对象程序设计>实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 ...

  10. Alpha冲刺No.5

    一.站立式会议 在助教帮助下,优先解决404的问题,将demo移植到自己项目上. 进一步制作界面. 将已做好的内容,移植到手机做部分测试,能够在同一路由子网内登录数据库. 二.实际项目进展 已经解决了 ...