首页 > 代码库 > python运算符重载

python运算符重载

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
1、打印操作会首先尝试__str__和str内置函数,他通常返回一个用户友好显示。__repr__用于所有其他环境,用于交互式模式下提示回应以及repr函数,如果没有使用__str__,则会使用printstr。它通常返回一个编码字符串,可以用来重新创建对象,或则给开发者一个详细的显示。总而言之,除了当定义一个__str__的时候,使用printstr。然而需要注意,如果没有定义__str__,打印还是使用__repr__,反过来不成立。在交互模式下,只适用__repr__,并且根本不尝试__str__.
 
2、__str__,__repr__都必须返回字符串,返回其他类型会抱错。还有一个需要注意的是,__str__的用户友好显示可能只有对象出现在一个打印操作的顶层时候才应用,嵌套 到较大对象中 的对象 可能用其__repr__或默认方法打印。
 
                例如:
 
                class  Printer:
 
                                def __init__(self,val):
 
                                                self.val = val
 
                                def __str__(self):
 
                                                return str(self.val)
 
                obj = [Printer(2),Printer(3)]
 
                for x in obj:
 
                                print(x)  #输出:2 3
 
                print(obj)  #输出:[<__main__.Printer object at 0xb73c808c>, <__main__.Printer object at 0xb73c80ac>]
 
                但是__repr__能够解决前面提的那个问题
 
                class  Printer:
 
                                def __init__(self,val):
 
                                                self.val = val
 
                                def __repr__(self):
 
                                                return str(self.val)
 
                obj = [Printer(2),Printer(3)]
 
                for x in obj:
 
                                print(x)  #输出:2 3
 
                print(obj)  #输出:2,3
 
3、右侧加法和原处加法:__radd__,__iadd__
 
                class adder:
 
                                def __init__(self,value=0):
 
                                                self.data = value
 
                                def __add__(self,,other):
 
                                                self.data+=other
 
                adder只是在+左边是对象时使用,如果要支持右侧使用实例对象,则需要重载 __radd__.
 
                例如:
 
                class Commuter:
 
                def __init__(self,val):
 
                                self.val = val
 
                def __add__(self,other):
 
                                print(‘add‘,self.val,other)
 
                                return self.val+other
 
                def __radd__(self,other):
 
                                print(‘radd‘,self.val,other)
 
                                return other+self.val   #这个 顺序无所谓,只是在调用的时候很位置很重要
 
                x = Commuter(88)
 
                y = Commuter(99)
 
                print(x+1)
 
                print(‘#‘*8)
 
                print(1+y)
 
                print(‘$‘*8)
 
                print(x+y)
 
                #输出结果如下:
 
                add 88 1
 
                89
 
                ########
 
                radd 99 1
 
                100
 
                $$$$$$$$
 
                add 88 <__main__.Commuter object at 0xb71e8c2c>
 
                radd 99 88
 
                187
 
                
 
                原处加法: __iadd__或者__add__但是__iadd__更高效
 
                class Number:
 
                                def __init__(self,val):
 
                                                self.val = val
 
                                def __iadd__(self,other):
 
                                                self.val+=other
 
                                                return self
 
                x = Number(5)
 
                x+=1
 
                x+=1
 
                print(x.val)  #输出:7
 
                或者
 
                class Number:
 
                                def __init__(self,val):
 
                                                self.val = val
 
                                def __add__(self,other):
 
                                                return Number(self.val+other)
 
4、call表达式:__call__ 
 
                有关python的__call__在官方文档上有这么一句解释 (http://docs.python.org/reference/datamodel.html?highlight=__call__#object.__call__)
 
                object.__call__(self[, args...])
 
                Called when the instance is “called” as a function; if this method is defined, x(arg1, arg2, ...) is a shorthand for x.__call__(arg1, arg2, ...).
 
                当把一个实例当作方法来调用的时候,形如instance(arg1,args2,...),那么实际上调用的就是 instance.__call__(arg1,arg2,...)
 
                例如:
 
                class Prod:
 
                def __init__(self,value):
 
                                self.value = value
 
                def __call__(self,other):
 
                                return self.value *other
 
                x = Prod(2)
 
                print(x(3))  #输出:6
 
5、比较:__lt__,__gt__和其他方法
 
                比较运算没有位置限制。
 
                比较运算没有隐士关系,比如说 == 为真并不以为着 !=为假
 
                python2.6中如果没有定义更为具体的比较方法,对其使用一个__cmp__或者内置cmp函数。
 
                cmp( x, y)
 
                Compare the two objects x and y and return an integer according to the outcome. The return value is negative if x < y, zero if x == y and strictly positive if x > y.
 
                
 
                class C:
 
                def  __init__(self,data):
 
                                self.data = data
 
                def __gt__(self,other):
 
                                return self.data > other
 
                def __lt__(self,other):
 
                                return self.data < other
 
                x = C(‘spam‘)
 
                print(‘1‘,x >‘ham‘)
 
                print(‘2‘,‘ham‘> x)
 
                print(‘3‘,x < ‘ham‘)
 
                print(‘4‘,‘ham‘ <x)
 
                y = C(‘ham‘)
 
                print(‘5‘,x<y)
 
                print(‘6‘,x>y)
 
6、布尔测试:__bool__,__len__
 
                在布尔环境中,python首先尝试__bool__来获取一个直接布尔值,然后如果没有该方法,就尝试__len__类根据对象的长度确定 一个真值。
 
7、对象析构函数:__del__
 
                每当实例产生时,就会调用__init__构造函数,每当 实例空间被回收时,就会执行析构函数。
 
                class Life:
 
                                def __init__(self,name=‘unknow‘):
 
                                                print(‘hello ‘,name)
 
                                                self.name = name
 
                                def __del__(self):
 
                                                print(‘Goodbye‘,self.name)
 
                brain = Life(‘Brain‘)#输出 hello brain
 
                brain = ‘loretta‘   #输出: Goodbye brain