目录
- 前言
- 基本魔法方法
- 属性相关
- 比较操作符
- 算数运算符
- 反运算
- 增量赋值运算符
- 一元操作符
- 类型转换
- 上下文管理器
- 容器类型
- 一览表
前言
Python 的对象天生拥有一些神奇的方法,它们总被双下划线所包围,它们是面向对象的 Python 的一切。它们是可以给你的类增加魔力的特殊方法,如果你的对象实现(重载)了某一个魔法方法,那么这个方法就会在特殊的情况下自动被 Python 所调用。
这些自动调用的方法可以帮你实现很多看起来不可思议的事,比如让 1+2 的结果等于-1,让 1-2 的结果等于3。下面我们就来详细的了解这些充满魔力的方法。
基本的魔法方法
1、 __new __(cls[,*args]) 方法
功能:创建一个对象(由 object 提供,一般不需要重写)。
参数:第一个参数 cls 表示包含该方法的类,它是自动传参;参数 more 是一个不定长参数,可有可无。
返回值:一个对象(一般是该类的实例对象)。
应用场景:主要用于继承一个不可变的类型,比如 str 等
# 例如下
class MyText(str):
def __new__(cls, string):
# 该方法可以在实例化之前对对象进行更改操作
string = string.upper()
# 返回对象
return super().__new__(cls, string)
# return string
# 这种返回的话 sample 就是和字符串类型数据,同时__init__也不会被执行
def __init__(self, str1):
self.str1 = str1
sample = MyText("I love you")
print(sample)
# I LOVE YOU
PS:实例化对象时,首先调用__new__方法为对象分配存储空间,并返回对象的引用。解释器获取到对象的引用后,会将其作为第一个参数传递给__init__方法。若没有返回该类的实例对象,则__init__方法就不会被调用。
2、__init __(self[, *args]) 方法
功能:初始化实例对象
参数:self 表示对象本身,也可以有其他参数
返回值:不需要返回值
应用场景:当你想要对象在创建时就初始化某些属性
# 例如下
class MyText(object):
name = None
age = 18
hobby = None
def __init__(self, name, age, hobby):
self.name = name
self.age = age
self.hobby = hobby
sample = MyText('阿强', '20', '阿珍')
print(sample.__dict__)
# {'name': '阿强', 'age': '20', 'hobby': '阿珍'}
PS:__init__方法也叫构造器,它是实例化对象时自动调用的第二个方法。若没有定义该方法,则实例化对象时就会自动调用其父类的__init__方法
3、__del __(self) 方法
功能:析构器,定义对象在内存中被释放时的行为
参数:self 代表对象本身,也可以有其他参数
返回值:无
应用场景:Python自带垃圾回收机制,但它只能回收用户级资源,而不能自动回收系统资源。故当一个对象同时拥有用户级(Python程序)与内核级(系统)两种资源时,就必须在清除对象的同时回收系统资源(如关闭文件等),这就用到了__del__方法
# 例如下
class MyText(object):
def __init__(self, file_name):
self.file_name = file_name
def __del__(self):
self.file_name.close()
del self.file_name
print('我被回收了哦')
# 关闭文件
sample = MyText(open('b.txt', 'a'))
print('1234', file=sample.file_name)
sample1 = sample
del sample
# 此处并没有真正的删除对象,而是使对象的引用计数减一,(解除了变量名sample与对象的绑定)
# 所以 del 并不是真正的删除对象,而是删除对象的引用
# print(sys.getrefcount(sample1)) # 通过这种方法获取引用计数
print('----------')
# 关于Python的回收机制
'''
Python 采用自动引用计数(ARC)方式来回收对象所占用的空间,当程序中有一个变量引用该 Python 对象时,
Python 会自动保证该对象引用计数为 1;当程序中有两个变量引用该 Python 对象时,Python 会自动保证该对象引用计数为 2,
依此类推,如果一个对象的引用计数变成了 0,则说明程序中不再有变量引用该对象,表明程序不再需要该对象,因此 Python 就会回收该对象。
'''
PS:1、并不是对一个变量执行 del 操作,该变量所引用的对象就会被回收,只有当对象的引用计数变成 0 时,该对象才会被回收。
2、如果父类提供了 __del__方法,则子类重写 __del__方法时必须显式调用父类的 __del__方法,这样才能保证合理地回收父类实例的部分属性。
4、__call __(self, *args, **kwargs) 方法
功能:允许并定义一个对象像函数一样被调用时的行为
参数:self 表示对象本身,args 和 kwargs 表示两个不定长参数
返回值:任意数量和类型的对象
# 例如下
class MyText(object):
def __call__(self, *args, **kwargs):
my_sum = 0
for item in args:
my_sum += item
return my_sum
sample = MyText()
print(sample(1, 2, 3, 4, 5))
# 15
5、__repr __(self) 方法
功能:定义对象被 repr() 函数或互交式解释器调用时的行为,该方法一般面向程序设计者
参数:self 表示对象本身
返回值:必须是一个字符串,否则抛出异常
# 例如下
class MyText:
def __repr__(self) -> str:
return 'My is repr'
sample = MyText()
print(sample) # My is repr
print(repr(sample)) # My is repr
6、__str __(self) 方法
功能:定义对象被 str()函数调用时的行为, 一般面向程序使用者
参数:self 代表对象本身
返回值:必须是字符串,否则抛出异常
class MyText:
name = 1
# def __repr__(self) -> str:
# return '嗯哼'
def __str__(self):
return 'My is str'
sample = MyText()
print(sample) # My is str
print(str(sample)) # My is str
关于__repr__和__str__方法的总结:
1、如果 __repr__和__str__都没有被定义, 那么print(对象),print(str(对象)),print(repr(对象))都会输出对象的地址
2、如果只有__repr__被定义,那么那么print(对象),print(str(对象)),print(repr(对象))都会输出该方法的返回值
3、如果只有__str__被定义,那么print(对象)和print(str(对象))会输出该方法的返回值,print(repr(对象))会输出对象的地址
4、如果两个都被定义,那么print(对象)会输出__str__方法的返回值,print(str(对象)),print(repr(对象))会输出各自方法的返回值
简单来说,__str__可以被__repr__代替(__str__没有定义时),反之不行,但__str__的优先级更高
7、__format __(self, format_spec) 方法
功能:定义对象被format()函数调用时的行为,常用于字符串的格式化输出
参数:self代表一个对象;format_spec表示格式控制符(可自定义),它将接收’:‘后面的字符串(如’{0: string}’.format(object) ,会将字符串’string’传给format_spec)
返回值:必须是一个字符串,否则抛出异常
# 例如下
date_dic = {
'ymd': '{0.year}:{0.month}:{0.day}',
'dmy': '{0.day}/{0.month}/{0.year}',
'mdy': '{0.month}-{0.day}-{0.year}',
}
class MyText:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
def __format__(self, format_spec):
if not format_spec or format_spec not in date_dic:
format_spec = 'ymd'
fmt = date_dic[format_spec]
return fmt.format(self)
d1 = MyText(2019, 9, 17)
print('{0:ymd}'.format(d1)) # 2019:9:17
# 等同于 print(format(d1, 'ymd'))
PS:这个方法本质上并没有改变 format()函数的功能,而是改变了传入的 format()函数的参数(format函数详解)
8、__len __(self) 方法
功能:定义对象被 len() 函数调用时的行为
参数:self 表示对象本身
返回值:必须是一个整数,否则会抛出异常
# 例如下
class MyTest(object):
def __init__(self):
self.name = '阿珍'
self.age = 18
def __len__(self):
# len() 函数一般返回对象(序列)的长度或元素个数
return len(self.__dict__)
sample = MyTest()
print(len(sample)) # 2
# PS: 如果对象的类没有实现__len__方法,那么用len()函数调用非序列对象就会出错
9、__dir __(self) 方法
功能:定义对象被 dir() 函数调用时的行为
参数:self 表示对象本身
返回值:一个可迭代对象
"""dir() 函数解析
功能:不带参时:返回当前范围内的变量、方法和定义的类型列表
带参数时:返回参数的属性、方法列表;如果参数提供了__dir__方法,该方法将被调用,
如果没有提供,则最大限度地收集参数的信息
返回值:模块或参数的属性列表(按字母排序)
"""
# 例如下
class MyTest(object):
def __init__(self):
self.name = '阿珍'
self.age = 18
def __dir__(self) -> 'Iterable[str]':
dic = self.__dict__.copy()
if 'name' in dic:
dic.pop('name')
return dic
# 如果不是可迭代对象 dir() 函数会抛出异常,但sample.__dir__()不会
sample = MyTest()
print(dir(sample)) # ['age']
10、__hash __(self) 方法
功能:定义对象被 hash() 函数调用时的行为
参数:self 表示对象自己
返回值:一个整数,表示对象的哈希值
""" hash(object) 函数解析
功能:获取一个对象的哈希值,
参数:可以是数值、字符串、实例对象等,不可以是list、set、dict
返回值:一个整数,表示参数的哈希值
注: 能够使用hash函数得到结果的,就是可哈希数据,也就是不可变数据类型
反之,不能被哈希的数据就是可变数据类型。
"""
# 例如下
class MyTest(object):
def __init__(self):
self.name = '阿珍'
self.age = 18
def __hash__(self):
return hash(str(self))
sample = MyTest()
print(hash(sample)) # 7257110065872306162
属性相关
1、__getattribute __(self, item) 方法
功能:定义实例对象的属性被访问时的行为(不管该属性是否存在,另:通过类名访问属性不会调用该方法)
参数:self 表示对象本身,item 是一个字符串,表示属性名字
返回值:默认为 None,返回值会自动返回给触发它的对象,一般通过return super().getattribute(item) 返回 item 属性的值。
# 例如下
class MyTest:
def __init__(self, age):
self.age = age
def __getattribute__(self, item):
return super().__getattribute__(item)
# 在这种方法下
# return self.item # 会无限递归
# return self.__dict__[item] # 也会无限递归
sample = MyTest(18)
print(sample.age) # 18
2、__getattr __(self, item) 方法
功能:该方法定义了用户试图访问一个不存在的属性时的行为
参数:self 指对象本身,item 是一个字符串,代表欲访问属性的名字
返回值:默认为 None,返回值会自动返回给触发它的对象
# 例如下
class MyTest:
def __getattr__(self, item):
return 18
sample = MyTest()
# __getattr__的返回值被sample.age接收,
# 这里的接收并不是赋值操作,更像是替换。对象sample仍没有age属性。
print(sample.age) # 18
# 使用 '.' 操作符访问对象时触发此方法
print(sample.__dict__) # {}
PS:当__getattribute__和__getattr__同时存在时,会先执行__getattribute__方法,若该方法能正常返回一个值,那么__getattr__方法就不会被执行。若该方法没有正常返回一个值(产生了异常(AttributeError)或属性不存在),则__getattr__方法就会在__getattribute__之后被执行。
3、__setattr __(self, key, value) 方法
功能:该方法定义当一个属性被设置(创建或修改)时的行为
参数: self 代表对象本身;key是一个字符串,代表属性的名字;value代表属性的值.
返回值: 无
# 例如下
class MyTest:
def __setattr__(self, key, value):
self.__dict__[key] = value
# self.key = value # 不能用这种方法,会无限递归
sample = MyTest()
sample.age = 10
# 使用'.'操作符时触发此方法
print(sample.__dict__) #{'age': 10}
4、__delattr __(self, item) 方法
功能:定义当一个属性被删除时的行为
参数:self 表示对象本身;item 是一个字符串,表示被删除属性的名字
返回值:无
# 例如下
class MyTest:
def __delattr__(self, item):
print('{}属性将被删除'.format(item))
self.__dict__.pop(item)
# del self.item # 不能用这种方法,会无限递归
sample = MyTest()
sample.age = 10
del sample.age # age属性将被删除
# 使用'.'操作符时触发此方法
5、__set __(self, instance, value) 方法
功能:定义当描述符的值被设置或修改时的行为
参数:self 表示描述符类的实例对象,instance 表示被代理类的实例对象,value 表示属性的值
返回值:无
# 例如下
class MyTest:
# 至少定义了__get__()、__set__()或__delete__()中的一个方法的类叫做描述符
def __init__(self, name):
self.name = name
def __set__(self, instance, value):
instance.__dict__[self.name] = value
class TextTwo:
name = MyTest('name1')
# 注意,传入MyText类的参数即时最好是对象(name)名的字符串,
# 因为传入的参数会作为本类实例对象属性的名字
sample = TextTwo()
sample.name = 10
print(sample.__dict__) # {'name1': 10}
6、__get __(self, instance, owner) 方法
功能:定义描述符的值被取得时的行为
参数:self 表示描述符类的实例对象,instance 表示被代理类的实例对象,owner 表示被代理的类
返回值:一般为相应属性的值
# 例如下
class MyTest:
def __init__(self, name):
self.name = name
def __get__(self, instance, owner):
return instance.__dict__[self.name]
def __set__(self, instance, value):
instance.__dict__[self.name] = value
class TextTwo:
name = MyTest('name1')
sample = TextTwo()
sample.name = 11
print(sample.name) # 11
print(sample.__dict__) # {'name1': 11}
7、__delete __(self, instance) 方法
功能:定义描述符的值被删除时的行为
参数:self 表示描述符类的对象,instance 表示被代理的类的实例对象
返回值:无
# 例如下
class MyTest:
def __init__(self, name):
self.name = name
def __set__(self, instance, value):
instance.__dict__[self.name] = value
def __delete__(self, instance):
print('属性的被删除了')
instance.__dict__.pop(self.name)
class TextTwo:
name = MyTest('name1')
sample = TextTwo()
sample.name = 11
# print(sample.__dict__)
del sample.name # 属性被删除了
print(sample.__dict__) # {}
PS:描述符的作用是通过组合的方式代理另外一个类的属性(该属性必须是类属性),取得代理权后,对这个属性的删改查操作都由描述符来完成。描述符常用来实现对另一个类的属性的格式控制操作。
比较操作符
1、__gt __(self, other) 方法
功能:定义大于号的行为:x > y, 相当于 x.__gt __(y)
参数:self 表示大于号左边的对象,other 表示大于号右边的对象
返回值:一般是一个表达式,其结果为 False 或 True
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __gt__(self, other):
print('啊,哈哈哈嗝~')
return self.age > other.age
sample_1 = MyTest(18)
sample_2 = MyTest(19)
if sample_1 > sample_2:
print('yes')
# 啊,哈哈哈嗝~
2、__lt __(self, other) 方法
功能:定义小于号的行为:x < y, 相当于 x.__lt __(y)
参数:self 表示小于号左边的对象,other 表示小于号右边的对象
返回值:一般是一个表达式,其结果为 False 或 True
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __lt__(self, other):
print('啊,哈哈哈嗝~')
# return self.age < other.age
return self.age > other.age
sample_1 = MyTest(18)
sample_2 = MyTest(19)
if sample_1 < sample_2:
print('yes')
# 啊,哈哈哈嗝~
3、__eq __(self, other) 方法
功能:定义等于号的行为:x == y, 相当于 x.__eq __(y)
参数:self 表示等于号左边的对象,other 表示等于号右边的对象
返回值:一般是一个表达式,其结果为 False 或 True
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __eq__(self, other):
print('啊,哈哈哈嗝~')
return self.age == other.age
sample_1 = MyTest(18)
sample_2 = MyTest(18)
if sample_1 == sample_2:
print('yes')
# 啊,哈哈哈嗝~
# yes
4、__ge __(self, other) 方法
功能:定义大于等于号的行为:x >= y, 相当于 x.__ge __(y)
参数:self 表示大于等于号左边的对象,other 表示大于等于号右边的对象
返回值:一般是一个表达式,其结果为 False 或 True
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __ge__(self, other):
print('啊,哈哈哈嗝~')
return self.age >= other.age
sample_1 = MyTest(18)
sample_2 = MyTest(19)
if sample_1 >= sample_2:
print('yes')
# 啊,哈哈哈嗝~
5、__le __(self, other) 方法
功能:定义小于等于号的行为:x <= y, 相当于 x.__le __(y)
参数:self 表示小于等于号左边的对象,other 表示小于等于号右边的对象
返回值:一般是一个表达式,其结果为 False 或 True
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __le__(self, other):
print('啊,哈哈哈嗝~')
return self.age <= other.age
sample_1 = MyTest(18)
sample_2 = MyTest(19)
if sample_1 <= sample_2:
print('yes')
# 啊,哈哈哈嗝~
# yes
6、__ne __(self, other) 方法
功能:定义不等于号的行为:x != y, 相当于 x.__ne __(y)
参数:self 表示不等于号左边的对象,other 表示不等于号右边的对象
返回值:一般是一个表达式,其结果为 False 或 True
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __ne__(self, other):
print('啊,哈哈哈嗝~')
return self.age != other.age
sample_1 = MyTest(18)
sample_2 = MyTest(19)
if sample_1 != sample_2:
print('yes')
# 啊,哈哈哈嗝~
# yes
算数运算符
1、__add __(self, other) 方法
功能:定义加法的行为
参数:self 表示加号左边的对象,other 表示加号右边的对象
返回值:一般返回一个对象或一个值
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __add__(self, other):
return MyTest(self.age + other.age)
sample_1 = MyTest(18)
sample_2 = MyTest(10)
print((sample_1 + sample_2).age) # 28
2、__sub __(self, other) 方法
功能:定义减法的行为
参数:self 表示减号左边的对象,other 表示减号右边的对象
返回值:一般返回一个对象或一个值
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __sub__(self, other):
return MyTest(self.age - other.age)
sample_1 = MyTest(18)
sample_2 = MyTest(10)
print((sample_1 - sample_2).age) # 8
3、__mul __(self, other) 方法
功能:定义乘法的行为
参数:self 表示乘号左边的对象,other 表示乘号右边的对象
返回值:一般返回一个对象或一个值
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __mul__(self, other):
return MyTest(self.age * other.age)
sample_1 = MyTest(18)
sample_2 = MyTest(10)
print((sample_1 * sample_2).age) # 180
4、__truediv __(self, other) 方法
功能:定义真除法的行为
参数:self 表示除号左边的对象,other 表示除号右边的对象
返回值:一般返回一个对象或一个值
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __truediv__(self, other):
return MyTest(self.age / other.age)
sample_1 = MyTest(18)
sample_2 = MyTest(9)
print((sample_1 / sample_2).age) # 2.0
5、__floordiv __(self, other) 方法
功能:定义地板除除法的行为
参数:self 表示 ‘//’ 号左边的对象,other 表示 ‘//’ 号右边的对象
返回值:一般返回一个对象或一个值
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __floordiv__(self, other):
return MyTest(self.age // other.age)
sample_1 = MyTest(18)
sample_2 = MyTest(9)
print((sample_1 // sample_2).age) # 2
6、__mod __(self, other) 方法
功能:定义取模算法的行为
参数:self 表示取模号左边的对象,other 表示取模号右边的对象
返回值:一般返回一个对象或一个值
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __mod__(self, other):
return MyTest(self.age % other.age)
sample_1 = MyTest(18)
sample_2 = MyTest(10)
print((sample_1 % sample_2).age) # 8
7、__divmod __(self, other) 方法
功能:定义当对象被 divmod() 函数调用时的行为
参数:self 表示被除数,other 表示除数
返回值:返回一个元组,包含两个对象的商和余数
"""divmod(num_1, num_2) 函数解析
功能:除数和余数运算结果结合起来,返回一个包含商和余数的元组(num_1 // num_2, num_1 % num_2)。
参数:num_1 和 num_2 表示两个数字
返回值:一个元组,表示两个数的商和余数
"""
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __divmod__(self, other):
return (self.age // other.age), (self.age % other.age)
sample_1 = MyTest(18)
sample_2 = MyTest(10)
div_mod = divmod(sample_1, sample_2)
print(div_mod) # (1, 8)
8、__pow __(self, power, modulo=None) 方法
功能:定义当被 pow() 调用或 ** 运算时的行为
参数:self 表示对象本身; power 表示指数对象; modulo 表示取模数,默认为 None
返回值:一般返回一个对象或一个值
PS:查阅资料过程中看到有些博客中写的是: 定义被 power() 函数调用时的行为。经试验发现内置函数中没有 power() 函数,且该魔法方法定义的是 pow() 函数的行为。
"""pow(x, y[, z]) 函数解析
功能:求 x 的 y 次方,若 z 不为 None,则再对结果取模。相当于 pow(x, y) % z
参数:x, y, z 表示三个数值表达式,其中 z 默认为 None
返回值:x 的 y 次方的值,或 x 的 y 次方再对 z 取模的值
"""
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __pow__(self, power, modulo=None):
print('这里是__pow__')
return pow(self.age, power.age, modulo)
sample_1 = MyTest(3)
sample_2 = MyTest(2)
power_ = pow(sample_1, sample_2)
print(power_)
# 这里是__pow__
# 9
9、__lshift __(self, other) 方法
功能:定义按位左移位的行为:<<
参数:self 表示左移位号左边的对象, other 表示左移位号右边的对象
返回值:一个整数
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __lshift__(self, other):
return sample.age << other
sample = MyTest(1)
print(sample << 2) # 4
10、__rshift __(self, other) 方法
功能:定义按位右移位的行为:>>
参数:self 表示右移位号左边的对象, other 表示右移位号右边的对象
返回值:一个整数
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __rshift__(self, other):
return sample.age >> other
sample = MyTest(4)
print(sample >> 2) # 1
11、__and __(self, other) 方法
功能:定义按位与操作的行为:&
参数:self 表示按位与运算符左边的对象, other 表示按位与运算符右边的对象
返回值:一个整数
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __and__(self, other):
return sample.age & other
# 0001 & 0011
sample = MyTest(1)
print(sample & 3) # 1
12、__or __(self, other) 方法
功能:定义按位或运算的行为:|
参数:self 表示按位或运算符左边的对象, other 表示按位或运算符右边的对象
返回值:一个整数
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __or__(self, other):
return sample.age | other
sample = MyTest(1)
print(sample | 2) # 3
13、__xor __(self, other) 方法
功能:定义按位或运算的行为:^
参数:self 表示按位异或运算符左边的对象, other 表示按位异或运算符右边的对象
返回值:一个整数
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __xor__(self, other):
return sample.age ^ other
sample = MyTest(1)
print(sample ^ 3) # 2
反运算
1、__radd __(self, other) 方法
功能:定义当左操作数不支持加法操作时的行为
参数:self 表示加号右边的对象,other 表示加号左边的对象
返回值:一般返回一个对象或一个值
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __radd__(self, other):
print(self.age, other.age) # 8 10
return self.age + other.age
a = A(10)
b = B(8)
print(a + b) # 18
# c = B(20)
# print(b + c) # unsupported operand type(s) for +: 'B' and 'B'
# 同类型对象之间不会调用__radd__方法
PS: 关于算数运算符和反运算的魔法方法说明:
当运算符的左操作数没有提供算数运算符的魔法方法时,就会检查右操作数是否提供有反运算的魔法方法,若有,就会按照反运算方法的定义来执行相应的算数运算,若无,抛出 TypeError 的异常。
以加法运算 a + b 为例,详细如图:
2、__rsub __(self, other) 方法
功能:定义当左操作数不支持减法运算时的行为
参数:参数:self 表示减号右边的对象,other 表示减号左边的对象
返回值:一般返回一个对象或一个值
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __rsub__(self, other):
return other.age - self.age
a = A(3)
b = B(2)
print(a - b) # 1
3、__rmul __(self, other) 方法
功能:定义左操作数不支持乘法运算时的行为
参数:self 表示乘号右边的对象,other 表示乘号左边的对象
返回值:一般返回一个对象或一个值
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __rmul__(self, other):
return other.age * self.age
a = A(5)
b = B(2)
print(a * b) # 10
4、__rtruediv __(self, other) 方法
功能:定义当左操作数不支持真除法运算时的行为
参数:self 表示除号右边的对象,other 表示除号左边的对象
返回值:一般返回一个对象或一个值
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __rtruediv__(self, other):
return other.age / self.age
a = A(3)
b = B(2)
print(a / b) # 1.5
5、__rfloordiv __(self, other) 方法
功能:定义左操作数不支持地板除除法操作时的行为
参数:self 表示’//‘号右边的对象,other 表示’//'号左边的对象
返回值:一般返回一个对象或一个值
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __rfloordiv__(self, other):
return other.age // self.age
a = A(18)
b = B(7)
print(a // b) # 2
6、__rmod __(self, other) 方法
功能:定义左操作数不支持取模算法时的行为
参数:self 表示取模号右边的对象,other 表示取模号左边的对象
返回值:一般返回一个对象或一个值
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __rmod__(self, other):
return other.age % self.age
a = A(5)
b = B(2)
print(a % b) # 1
7、__rdivmod __(self, other) 方法
功能:定义当传入 divmod() 函数的第一个参数没有提供 __divmod__方法时的行为
参数:self 表示传入 divmod() 函数的第二个参数,other 表示传入 divmod() 函数的第一个参数
返回值:返回一个元组,包含两个对象的商和余数
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __rdivmod__(self, other):
return other.age // self.age, other.age % self.age
a = A(3)
b = B(2)
print(divmod(a, b)) # (1, 1)
8、__rpow __(self, other) 方法
功能:定义当传入 pow() 函数的第一个参数或 ** 运算的左操作数没有提供__pow__方法时的行为
参数:self 表示传入 pow() 函数的第二个参数或 ** 运算符的右操作数, other 表示传入 pow() 函数的第一个参数或 ** 运算符的左操作数
返回值:一般返回一个对象或一个值
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __rpow__(self, other):
return pow(other.age, self.age)
a = A(3)
b = B(2)
print(pow(a, b)) # 9
9、__rlshift __(self, other) 方法
功能:定义左操作数不支持按位左移位操作时的行为
参数:self 表示左移位号右边的对象, other 表示左移位号左边的对象
返回值:一个整数
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __rlshift__(self, other):
return other.age << self.age
a = A(1)
b = B(2)
print(a << b) # 4
10、__rrshift __(self, other) 方法
功能:定义当左操作数不支持按位右移位操作时的行为
参数:self 表示右移位号右边的对象, other 表示右移位号左边的对象
返回值:一个整数
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __rrshift__(self, other):
return other.age >> self.age
a = A(3)
b = B(1)
print(a >> b) # 1
11、__rand __(self, other) 方法
功能:定义当左操作数不支持按位与运算操作时的行为
参数:self 表示按位与运算符右边的对象, other 表示按位与运算符左边的对象
返回值:一个整数
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __rand__(self, other):
return self.age & other.age
a = A(2)
b = B(3)
print(a & b) # 2
12、__or __(self, other) 方法
功能:定义当左操作数不支持按位或运算操作的行为
参数:self 表示按位或运算符右边的对象, other 表示按位或运算符左边的对象
返回值:一个整数
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __ror__(self, other):
return other.age | self.age
a = A(1)
b = B(2)
print(a | b) # 3
13、__xor __(self, other) 方法
功能:定义当左操作数不支持按位异或运算操作时的行为
参数:self 表示按位异或运算符右边的对象, other 表示按位异或运算符左边的对象
返回值:一个整数
# 例如下
class A(object):
def __init__(self, age):
self.age = age
class B(object):
def __init__(self, age):
self.age = age
def __rxor__(self, other):
return other.age ^ self.age
a = A(3)
b = B(2)
print(a ^ b) # 1
增量赋值运算符
1、__iadd __(self, other) 方法
功能:定义赋值加法的行为:+=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __iadd__(self, other):
self.age += other
return self
sample = MyTest(10)
sample += 10
print(sample.age) # 20
2、__isub __(self, other) 方法
功能:定义赋值减法的行为:-=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __isub__(self, other):
self.age -= other
return self
sample = MyTest(20)
sample -= 10
print(sample.age) # 10
3、__imul __(self, other) 方法
功能:定义赋值乘法的行为:*=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __imul__(self, other):
self.age *= other
return self
sample = MyTest(10)
sample *= 10
print(sample.age) # 100
4、__itruediv __(self, other) 方法
功能:定义赋值真除法的行为:/=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __itruediv__(self, other):
self.age /= other
return self
sample = MyTest(10)
sample /= 10
print(sample.age)# 1.0
5、__ifloordiv __(self, other) 方法
功能:定义赋值地板除法的行为://=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __ifloordiv__(self, other):
self.age //= other
return self
sample = MyTest(10)
sample //= 9
print(sample.age) # 1
6、__imod __(self, other) 方法
功能:定义赋值取模算法的行为:%=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __imod__(self, other):
self.age %= other
return self
sample = MyTest(3)
sample %= 2
print(sample.age) # 1
7、__ipow __(self, other) 方法
功能:定义赋值幂运算的行为:**=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __ipow__(self, other):
self.age **= other
return self
sample = MyTest(10)
sample **= 2
print(sample.age) # 9
8、__ilshift __(self, other) 方法
功能:定义赋值按位左移的行为:<<=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __ilshift__(self, other):
self.age <<= other
return self
sample = MyTest(1)
sample <<= 2
print(sample.age) # 4
9、__irshift __(self, other) 方法
功能:定义赋值按位左移的行为:>>=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __irshift__(self, other):
self.age >>= other
return self
sample = MyTest(4)
sample >>= 2
print(sample.age) # 1
10、__iand __(self, other) 方法
功能:定义赋值按位与操作的行为:&=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __iand__(self, other):
self.age &= other
return self
sample = MyTest(3)
sample &= 2
print(sample.age) # 2
11、__ior __(self, other) 方法
功能:定义赋值按位或操作的行为:|=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
、class MyTest(object):
def __init__(self, age):
self.age = age
def __ior__(self, other):
self.age |= other
return self
sample = MyTest(1)
sample |= 2
print(sample.age) # 3
12、__ixor __(self, other) 方法
功能:定义赋值按位异或操作的行为:^=
参数:self 表示左操作对象,other表示右操作对象
返回值:一个对象,该对象一般与左操作数同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __ixor__(self, other):
self.age ^= other
return self
sample = MyTest(1)
sample ^= 3
print(sample.age) # 2
一元操作符
1、__abs __(self) 方法
功能:定义对象被 abs() 函数调用时行
参数:self 表示传入 abs() 函数的参数为
返回值:一个对象,一般与传入的参数对象同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __abs__(self):
if self.age < 0:
self.age = -sample.age
return self
sample = MyTest(-18)
sample = abs(sample)
print(sample.age) # 18
2、__pos __(self) 方法
功能:定义正号的行为:+x
参数:self 表示正号右边的对象
返回值:一个对象,一般与正号右边对象同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __pos__(self):
if self.age < 0:
self.age = -sample.age
return self
sample = MyTest(-18)
sample = +sample
print(sample.age) # 18
3、__neg __(self) 方法
功能:定义负号的行为:-x
参数:self 表示负号右边的对象
返回值:一个对象,一般与负号右边对象同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __neg__(self):
if self.age > 0:
self.age = -sample.age
return self
sample = MyTest(18)
sample = -sample
print(sample.age) # -18
4、__invert __(self) 方法
功能:定义按位求反的行为:~x
参数:self 表示 ‘~’ 号右边的对象
返回值:一个对象,一般与 ‘~’ 号右边对象同类型
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __invert__(self):
self.age = ~sample.age
return self
sample = MyTest(5)
sample = ~sample
print(sample.age) # -6
类型转换
1、__int __(self) 方法
功能:定义当对象被 int() 函数调用时的行为
参数:self 表示对象本身
返回值:返回一个十进制整型数
""" int([num[, base=10]]) 函数解析
功能:将一个数字或字符串或提供了__int__方法的对象转换成整形
参数:num 表示一个数值(int、float),也可以是字符串或实现了__int__方法的对象
base 表示进制数,默认为十进制(如果显示提供该参数,则 num 必须是相应进制数的字符串表示)
返回值:十进制的整型数
"""
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __int__(self):
return int(self.age)
sample = MyTest('2019')
print(int(sample)) # 2019
2、__float __(self) 方法
功能:定义当对象被 float() 函数调用时的行为
参数:self 表示对象本身
返回值:返回一个十进制浮点数
""" float(num) 函数解析
功能:将整数或字符串或提供了__float__方法的对象转换成浮点数。
参数:num 表示一个整数,也可以是字符串或实现了__float__方法的对象
返回值:十进制的浮点数
"""
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __float__(self):
return float(self.age)
sample = MyTest('2019')
print(float(sample)) # 2019.0
3、__complex __(self) 方法
功能:功能:定义当对象被 complex() 函数调用时的行为
参数:self 表示对象本身
返回值:需要返回一个复数
""" complex([real[, imag]]) 函数解析
功能:用于创建一个值为 (real+imag*j) 的复数或者转化一个字符串或数为复数
参数:real 可以是任意数值(int、float、complex),也可以是字符串或实现了__complex__ 或 __float__方法的对象(如果 real 为字符串,就必须不提供 imag 参数)
imag 可以是任意数值,也可以是实现了__complex__ 或 __float__方法的对象
返回值:若无参,返回 0j;若没有提供 imag,返回 (real+0j);若提供了 imag,返回 real+imag*j
"""
# 例如下
class MyTest(object):
def __init__(self, comp):
self.comp = comp
def __complex__(self):
return complex(self.comp)
sample = MyTest('2+3j')
print(complex(sample)) # (2+3j)
4、__round __(self) 方法
功能:定义当对象被 round() 函数调用时的行为
参数:self 表示对象本身
返回值:一个浮点数
"""round(num, n=None)
功能:求浮点数 num 四舍五入后的近似值
参数:num 表示一个浮点数;n 为保留小数的位数,默认保留到整数位
返回值:返回浮点数 num 四舍五入后的近似值
PS:1、这里有一个坑,Python 2 与 Python 3 中的 round() 函数有细微的差别
具体为:
Python 2 :保留值将保留到离上一位更近的一端(四舍六入),如果距离两端一样远,则保留到离0远的一边。
如:round(0.5) == 1,round(-0.5) == -1
Python 3 :如果距离两边一样远,会保留到偶数的一边。
如:round(0.5) == 0, round(-0.5) == 0
2、round() 函数返回的结果还跟精度有关(具体请参考官方doc)
如:round(2.675, 2) == 2.67
"""
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __round__(self, n=None):
return round(self.age)
sample = MyTest(2019.925)
print(round(sample)) # 2020
5、__bool __(self) 方法
功能:定义对象被 bool() 函数调用时的行为
参数:self 表示对象自己
返回值:False 或 True
""" bool() 函数解析
功能:将给定的参数转换为布尔类型,如果没有参数,返回 False (bool 是 int 的子类)
参数:要转换的对象
返回值:False 或 True
"""
class MyTest(object):
def __init__(self):
self.name = '阿珍'
self.age = 18
def __bool__(self):
if len(self.__dict__) > 0:
return True
return False
sample = MyTest()
print(bool(sample)) # True
6、__bytes __(self) 方法
功能:定义对象被 bytes() 函数调用时的行为
参数:self 表示对象本身
返回值:一个 bytes 对象
"""
bytes 是字节组成的有序的不可变序列,其中字节的范围是[0,255]的整型数,这是一种不可变的数据类型
bytearray 是字节组成的有序的可变序列
bytes([source[, encoding[, errors]]]) 函数解析
功能:创建一个新的 bytes 对象,该对象是一个[0,255]区间内的整型数不可变序列
参数:如果 source 为整数,则返回一个长度为 source 的初始化数组,数组元素都为0;
如果 source 为字符串,则按照指定的 encoding 将字符串转换为字节序列;
如果 source 为可迭代类型,则元素必须为[0 ,255] 中的整数;
如果 source 为与 buffer 接口一致的对象,则此对象也可以被用于初始化 bytearray。
如果没有输入任何参数,默认就是初始化数组为0个元素。
encoding 表示编码类型
返回值:一个新的 bytes 对象
"""
class MyTest(object):
def __init__(self, age):
self.age = age
def __bytes__(self):
return bytes(self.age, encoding="utf-8")
sample = MyTest('12345')
print(bytes(sample))
7、__index __(self) 方法
功能:对象是被应用在切片表达式中时,实现整形强制转换
参数:self 表示对象本身
返回值:返回一个整型数
应用场景:如果你定义了一个可能在切片时用到的定制的数值类型,那么你应该定义__index __
# 例如下
class MyTest(object):
def __init__(self, age):
self.age = age
def __int__(self):
return int(self.age)
def __index__(self):
return int(self.age)
sample = MyTest(5)
string = '123456789'
print(string[:sample]) # 12345
PS: 如果 __index__方法被定义,则__int__方法也需被定义,且返回相同的值
上下文管理器
1、__enter __(self) 方法
功能:定义当使用 with 语句时的初始化行为
参数:self 表示上下文管理器对象
返回值:一个对象,会自动赋予上下文管理器实例化产生的对象或 with 语句 as 后面的变量
2、__exit __(self, exc_type, exc_val, exc_tb)方法
功能:定义当 whit 语句下的代码组被执行结束或异常终止后上下文管理器的行为,一般被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作
参数: self 表示上下文管理器对象
exc_type 表示捕获的异常类型,没有捕获异常则为 None
exc_val 表示捕获的异常的值,没有捕获异常则为 None
exc_tb 表示捕获的追溯信息,没有捕获异常则为 None
返回值:默认为 None,如果返回 True,那么异常会被清空
# __enter__和__exit__例如下
class MyOpen(object):
def __init__(self, fname, act='a'):
self.filename = fname
self.fileact = act
def __enter__(self) -> str:
self.myfname = open(self.filename, self.fileact)
print('这里在遇见with语句时执行,完成初始化工作')
return self.myfname
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is None:
print('with中的代码块没有出现异常:', exc_type)
self.myfname.close()
with MyOpen('上下文管理.txt') as myfname:
print('This is a test', file=myfname)
# 这里在遇见with语句时执行,完成初始化工作
# with中的代码块没有出现异常: None
容器类型
1、__getitem __(self, key)方法
功能:该方法定义了获取容器中指定属性时的行为,相当于self[key]
参数:self指对象本身,key是一个字符串,代表欲访问属性的名字
返回值:默认为 None,返回值会自动返回给触发它的对象
# 例如下
class MyTest:
def __init__(self, name):
self.name = name
def __getitem__(self, key):
return self.__dict__[key]
# return self[key] # 不可用这种方法,会无限递归
sample = MyTest('阿珍')
print(sample['name']) # 阿珍
# 使用 [] 操作符时触发此方法
2、__setitem __(self, key, value)方法
功能:该方法定义当一个容器的属性被设置(创建或修改)时的行为
参数: self 代表对象本身;key是一个字符串,代表属性的名字;value代表属性的值
返回值: 无
# 例如下
class MyTest:
def __setitem__(self, key, value):
self.__dict__[key] = value
# self[key] = value # 不能用这种方法,会无限递归
sample = MyTest()
sample['age'] = 10
3、__delitem __(self, key)方法
功能:定义当一个容器的属性被删除时的行为
参数:self表示对象本身;key是一个字符串,表示被删除属性的名字
返回值:无
# 例如下
class MyTest:
def __delitem__(self, key):
self.__dict__.pop(key)
# del self[name] # 不能用这种方法,会无限递归
sample = MyTest()
sample.age = 10
del sample['age']
4、__iter __(self)方法
功能:定义对象被 iter() 函数调用时的行为。主要用于返回一个迭代器对象
参数:self代表对象本身
返回值:必须是一个迭代器对象
PS:实现了该方法的对象称为可迭代对象
5、__next __(self)方法
功能:定义对象被 next() 函数调用时的行为。主要用于返回迭代的下一项
参数:self代表对象本身
返回值:一个值,是迭代的下一项
PS:实现了该方法的对象称为迭代器对象
# __iter__和__next__例如下
class Iter(object):
def __init__(self, x):
self.x = x
def __iter__(self):
return self
# 必须返回一个迭代器对象
def __next__(self):
# 实现了该方法的对象称为迭代器对象
self.x += 1
if self.x > 10:
raise StopIteration
return self.x
# 返回迭代的下一项
sample = Iter(1)
print(next(sample))
print(next(sample))
print(next(sample))
for i in sample:
print(i)
PS:迭代器和迭代器协议解析
6、__reversed __(self)方法
功能:定义当对象被 reversed() 函数调用时的行为
参数:self 表示对象本身
返回值:返回集合的倒序迭代器
# 例如下
"""reversed(sequence) 函数解析
功能:翻转迭代器的序列值
参数:一个序列
返回值:迭代器对象
PS: reversed() 函数返回值的迭代器对象只在第一次遍历时返回结果, 因为迭代器一次遍历之后就会迭代结束,当再次对这个迭代器对象迭代时,因为已经迭代完了,所以没有返回值。
"""
class MyTest:
def __init__(self, ages):
self.ages = ages
def __reversed__(self):
return reversed(self.ages)
sample = MyTest([1, 2, 3, 4, 5])
ite = reversed(sample)
for i in ite:
print(i, end=' ') # 5 4 3 2 1
for i in ite:
print(i, end=' ') # 这里没有输出
7、__contains __(self, item)方法
功能:定义当使用成员测试运算符 (in 或 not in) 时的行为
参数:self 表示对象本身;item 表示要测试的成员
返回值:False 或 True
# 例如下
class MyTest:
def __init__(self, ages):
self.ages = ages
def __contains__(self, item):
return item in self.ages
sample = MyTest([1, 2, 3, 4, 5])
if 3 in sample:
print('Yes') # Yes