运算符重载意味着在类方法中拦截内置的操作,这样当类的实例出现在内置操作中,Python会自动调用你的方法,并且方法的返回值变成了相应的操作结果。
class Number:
def __init__(self, start):
self.data = start
def __sub__(self, other):
return Number(self.data - other)
def main():
X = Number(5)
Y = X - 2
print(Y.data)
if __name__ == "__main__":
main()
# 输出:
# 3
方法 | 重载 | 调用 |
---|---|---|
__init__ | 构造函数 | 对象建立: X = Class(args) |
__del__ | 析构函数 | X对象收回 |
__add__ | 运算符+ | 如果没有__iadd__, X + Y, X += Y |
__or__ | 运算符 | (按位或) |
__repr__, __str__ | 打印, 转换 | print(X), repr(X), str(X) |
__call__ | 函数调用 | X(*args, **kargs) |
__getattr__ | 点号运算 | X.undefined |
__setattr__ | 属性赋值语句 | X.any = value |
__delattr__ | 属性删除 | del X.any |
__getattribute__ | 属性获取 | X.any |
__getitem__ | 索引运算 | X[key], X[i:j], 没__iter__时的for循环和其他迭代器 |
__setitem__ | 索引赋值语句 | X[key] = value, X[i:j] = sequence |
__delitem__ | 索引和分片删除 | def X[key], def X[i:j] |
__len__ | 长度 | len(X), 如果没有bool, 真值测试 |
__bool__(Python 3.0及之后版本), __nonzero__(Python 2.6及之后版本) | 布尔测试 | bool(X),nonzero(X) |
__lt__, __gt__, __le__, __ge__ | 大小比较 | X < Y, X > Y, X <= Y, X >= Y |
__eq__, __ne__(Python 3.0及之后版本), __cmp__(Python 2.6及之后版本) | 等值比较 | X == Y, X != Y |
__radd__ | 右侧加法 | other + X |
__iadd__ | 实地加法 | X += Y |
__iter__, __next__ | 迭代环境 | I = iter(X) next(I), 循环, map(F, X) |
__contains__ | 成员关系测试 | item in X |
__index__ | 整数值 | hen(X), bin(X), oct(X), O[X], O[X:] |
__enter__, __exit__ | 环境管理器 | with obj as var: |
__get__, __set__ | 描述符属性 | X.attr, X.attr = value, del X.attr |
__delete__ | del操作触发 | del(X)时执行 |
__new__ | 创建 | 在__init__之前创建对象 |
class Indexer:
data = [5, 6, 7, 8, 9]
def __getitem__(self, index):
return self.data[index]
def __setitem__(self, key, value):
self.data[key] = value
def main():
X = Indexer()
print(X[0])
print(X[2:4])
print(X[1:])
X[0] = 1
for item in X:
print(item)
print(1 in X)
print([num for num in X])
print(list(map(oct, X)))
(a, b, c, d, e) = X
print('---------------')
print(a)
print(b)
print(list(X))
print(tuple(X))
X.data = 'abcdefg'
print(''.join(X))
if __name__ == "__main__":
main()
'''
输出:
5
[7, 8]
[6, 7, 8, 9]
1
6
7
8
9
True
[1, 6, 7, 8, 9]
['0o1', '0o6', '0o7', '0o10', '0o11']
---------------
1
6
[1, 6, 7, 8, 9]
(1, 6, 7, 8, 9)
abcdefg
'''
class Squares:
def __init__(self, start, stop):
self.value = start - 1
self.stop = stop
def __iter__(self):
return self
def __next__(self):
if self.value == self.stop:
raise StopIteration
self.value += 1
return self.value ** 2
def main():
X = Squares(1, 5)
# I = iter(X) # 手动迭代也有效
print(next(X))
# X[1] # TypeError: 'Squares' object is not subscriptable,因为没有实现__getitem__方法
print([n for n in X])
print([n for n in X])
print([n for n in Squares(1,5)])
print('--------------------------')
X = Squares(1, 5)
I1 = iter(X)
I2 = iter(X)
print(next(I1))
print(next(I2))
print(next(I1))
print(next(I2))
if __name__ == "__main__":
main()
'''
输出:
1
[4, 9, 16, 25]
[]
[1, 4, 9, 16, 25]
--------------------------
1
4
9
16
'''
class Squares1:
def __init__(self, start, stop):
self.value = start - 1
self.stop = stop
def __iter__(self):
return self
def __next__(self):
if self.value == self.stop:
raise StopIteration
self.value += 1
return self.value ** 2
class Squares2:
def __init__(self, start, stop):
self.value = start - 1
self.stop = stop
def __iter__(self):
return Squares2(self.value + 1, self.stop)
def __next__(self):
if self.value == self.stop:
raise StopIteration
self.value += 1
return self.value ** 2
def main():
X = Squares1(1, 5)
I1 = iter(X)
I2 = iter(X)
print(next(I1))
print(next(I2))
print(next(I1))
print(next(I2))
print('------------------------------------')
Y = Squares2(1, 5)
I1 = iter(Y)
I2 = iter(Y)
print(next(I1))
print(next(I2))
print(next(I1))
print(next(I2))
if __name__ == "__main__":
main()
'''
输出:
1
4
9
16
------------------------------------
1
1
4
4
'''
在Python的迭代领域,类通常把in成员关系运算符实现为一个迭代,使用__iter__方法或者__getitem__方法,也可以编写一个__contains__方法。优先级为__contains__ > __iter__ > __getitem__。
class Iters:
def __init__(self, value):
self.data = value
def __getitem__(self, i):
print('get[%s]: ' % i, end='')
return self.data[i]
def __iter__(self):
print('iter=> ', end='')
self.ix = 0
return self
def __next__(self):
print('next: ',end='')
if self.ix == len(self.data): raise StopIteration
item = self.data[self.ix]
self.ix += 1
return item
def __contains__(self, item):
print('contains: ', end='')
return item in self.data
def main():
X = Iters([1, 2, 3, 4, 5])
print(3 in X)
for i in X:
print(i, end=' | ')
print()
print([i ** 2 for i in X])
print(list(map(bin, X)))
I = iter(X)
while True:
try:
print(next(I), end=' @ ')
except StopIteration:
break
if __name__ == "__main__":
main()
'''
输出:
contains: True
iter=> next: 1 | next: 2 | next: 3 | next: 4 | next: 5 | next:
iter=> next: next: next: next: next: next: [1, 4, 9, 16, 25]
iter=> next: next: next: next: next: next: ['0b1', '0b10', '0b11', '0b100', '0b101']
iter=> next: 1 @ next: 2 @ next: 3 @ next: 4 @ next: 5 @ next:
'''
class Iters:
def __init__(self, value):
self.data = value
def __getitem__(self, i):
print('get[%s]: ' % i, end='')
return self.data[i]
def __iter__(self):
print('iter=> ', end='')
self.ix = 0
return self
def __next__(self):
print('next: ',end='')
if self.ix == len(self.data): raise StopIteration
item = self.data[self.ix]
self.ix += 1
return item
'''
def __contains__(self, item):
print('contains: ', end='')
return item in self.data
'''
def main():
X = Iters([1, 2, 3, 4, 5])
print(3 in X)
for i in X:
print(i, end=' | ')
print()
print([i ** 2 for i in X])
print(list(map(bin, X)))
I = iter(X)
while True:
try:
print(next(I), end=' @ ')
except StopIteration:
break
if __name__ == "__main__":
main()
'''
输出:
iter=> next: next: next: True
iter=> next: 1 | next: 2 | next: 3 | next: 4 | next: 5 | next:
iter=> next: next: next: next: next: next: [1, 4, 9, 16, 25]
iter=> next: next: next: next: next: next: ['0b1', '0b10', '0b11', '0b100', '0b101']
iter=> next: 1 @ next: 2 @ next: 3 @ next: 4 @ next: 5 @ next:
'''
class Iters:
def __init__(self, value):
self.data = value
def __getitem__(self, i):
print('get[%s]: ' % i, end='')
return self.data[i]
def __iter__(self):
print('iter=> ', end='')
self.ix = 0
return self
def __next__(self):
print('next: ',end='')
if self.ix == len(self.data): raise StopIteration
item = self.data[self.ix]
self.ix += 1
return item
'''
def __contains__(self, item):
print('contains: ', end='')
return item in self.data
'''
def main():
X = Iters([1, 2, 3, 4, 5])
print(3 in X)
for i in X:
print(i, end=' | ')
print()
print([i ** 2 for i in X])
print(list(map(bin, X)))
I = iter(X)
while True:
try:
print(next(I), end=' @ ')
except StopIteration:
break
if __name__ == "__main__":
main()
'''
输出:
iter=> next: next: next: True
iter=> next: 1 | next: 2 | next: 3 | next: 4 | next: 5 | next:
iter=> next: next: next: next: next: next: [1, 4, 9, 16, 25]
iter=> next: next: next: next: next: next: ['0b1', '0b10', '0b11', '0b100', '0b101']
iter=> next: 1 @ next: 2 @ next: 3 @ next: 4 @ next: 5 @ next:
'''
class Iters:
def __init__(self, value):
self.data = value
def __getitem__(self, i):
print('get[%s]: ' % i, end='')
return self.data[i]
'''
def __iter__(self):
print('iter=> ', end='')
self.ix = 0
return self
def __next__(self):
print('next: ',end='')
if self.ix == len(self.data): raise StopIteration
item = self.data[self.ix]
self.ix += 1
return item
def __contains__(self, item):
print('contains: ', end='')
return item in self.data
'''
def main():
X = Iters([1, 2, 3, 4, 5])
print(3 in X)
for i in X:
print(i, end=' | ')
print()
print([i ** 2 for i in X])
print(list(map(bin, X)))
I = iter(X)
while True:
try:
print(next(I), end=' @ ')
except StopIteration:
break
if __name__ == "__main__":
main()
'''
输出:
get[0]: get[1]: get[2]: True
get[0]: 1 | get[1]: 2 | get[2]: 3 | get[3]: 4 | get[4]: 5 | get[5]:
get[0]: get[1]: get[2]: get[3]: get[4]: get[5]: [1, 4, 9, 16, 25]
get[0]: get[1]: get[2]: get[3]: get[4]: get[5]: ['0b1', '0b10', '0b11', '0b100', '0b101']
get[0]: 1 @ get[1]: 2 @ get[2]: 3 @ get[3]: 4 @ get[4]: 5 @ get[5]:
'''
class accesscontrol:
def __setattr__(self, key, value):
if key == 'age':
self.__dict__[key] = value
elif key == 'name':
self.__dict__[key] = value
else:
raise AttributeError(key + ' not allowed')
def __getattr__(self, item):
if item in self.__dict__:
return self.__dict__[item]
elif item == 'age':
return 0
elif item == 'name':
return ''
else:
raise AttributeError(item)
def main():
X = accesscontrol()
X.age = 100
X.name = 'Mike'
print(X.age)
print(X.name)
# X.gender = 'mile' # AttributeError: gender not allowed
X.__dict__['gender'] = 'mile'
print(X.gender)
if __name__ == "__main__":
main()
'''
输出:
100
Mike
mile
'''
class Printer:
def __init__(self, val):
self.val = val
def __str__(self):
return str(self.val)
#def __repr__(self):
# return str(self.val)
def main():
objs = [Printer(2), Printer(3)]
for x in objs:
print(x)
print(objs)
if __name__ == "__main__":
main()
'''
输出:
2
3
[<__main__.Printer object at 0x000001F208DB94C0>, <__main__.Printer object at 0x000001F20AA0E370>]
'''
class Printer:
def __init__(self, val):
self.val = val
# def __str__(self):
# return str(self.val)
def __repr__(self):
return str(self.val)
def main():
objs = [Printer(2), Printer(3)]
for x in objs:
print(x)
print(objs)
if __name__ == "__main__":
main()
'''
输出:
2
3
[2, 3]
'''
class Add1:
def __init__(self, val):
self.val = val
def __add__(self, other):
self.val += other
return self
class Add2:
def __init__(self, val):
self.val = val
def __add__(self, other):
return self.val + other
class Radd:
def __init__(self, val):
self.val = val
def __radd__(self, other):
return other + self.val
class Iadd:
def __init__(self, val):
self.val = val
def __iadd__(self, other):
self.val += other
return self
def main():
x = Add1(5)
x += 1
print(x.val)
x = x + 1
print(x.val)
x = Add2(5)
x += 1
print(x)
x = x + 1
print(x)
x = Radd(5)
x = 1 + x
print(x)
x = Iadd(5)
x += 1
print(x.val)
if __name__ == "__main__":
main()
'''
输出:
6
7
6
7
6
6
'''
class Compare:
data = 'abcde'
def __lt__(self, other):
return self.data < other
def __gt__(self, other):
return self.data > other
def __le__(self, other):
return self.data <= other
def __ge__(self, other):
return self.data >= other
def __eq__(self, other):
return self.data == other
def __ne__(self, other):
return self.data != other
def main():
X = Compare()
print('abcde' == X)
print('xyz' == X)
print('abcde' != X)
print('xyz' != X)
print('abc' < X)
print('xyz' < X)
print('abc' > X)
print('xyz' > X)
print('abc' <= X)
print('xyz' <= X)
print('abc' >= X)
print('xyz' >= X)
if __name__ == "__main__":
main()
'''
输出:
True
False
False
True
True
False
False
True
True
False
False
True
'''
class Bool:
data = 'abcde'
def __bool__(self):
if self.data:
return True
return False
class Len1:
data = 'abcde'
def __len__(self):
if self.data:
return True
return False
class Len2:
data = 'abcde'
def __len__(self):
return len(self.data)
def main():
X = Bool()
print(bool(X))
X = Len1()
print(bool(X))
X = Len2()
print(len(X))
if __name__ == "__main__":
main()
'''
输出:
True
True
5
'''
class Life:
def __init__(self, name='unknow'):
print('Hello', name)
self.name = name
def __del__(self):
print('Goodbye', self.name)
def main():
X = Life('John')
del(X)
if __name__ == "__main__":
main()
'''
输出:
Hello John
Goodbye John
'''
class Prod:
def __init__(self, value):
self.value = value
def __call__(self, *args):
return self.value * sum(args)
def main():
X = Prod(2)
print(X(3, 4, 5, 6))
if __name__ == "__main__":
main()
'''
输出:
36
'''
以上,欢迎各位读者朋友提出意见或建议。
欢迎阅读笔者后续博客,各位读者朋友的支持与鼓励是我最大的动力!
written by jiong
几曾随逝水,
岂必委芳尘?