1. The construction and destruction made
Magic methods is surrounded by a double underscore
__init__()
method
__init__
The method is not the default parameters, return value none. Examples of the class object initialization steps required to clear the override function
>>> class Rectangle:
def __init__(self,x,y):
self.x = x
self.y = y
def getPeri(self):
return (self.x+self.y)*2
def getArea(self):
return self.x * self.y
>>> rect = Rectangle(3,4)
>>> rect.getPeri()
14
>>> rect.getArea()
12
>>> #init返回值一定是None
>>> class A:
def __init__(self):
return "A"
>>> a = A()
Traceback (most recent call last):
File "", line 1, in
a = A()
TypeError: __init__() should return None, not 'str'
__new__()
method
__new__()
The method returns an instance of an object when instantiating the object, the parameter is CLS, the first method is called
>>> class CapStr(str):
def __new__(cls,string):
string = string.upper()
return str.__new__(cls,string)
>>> a = CapStr("I love FishC.com")
>>> a
'I LOVE FISHC.COM'
__del__()
method
__del__()
The method is called when the object is about to be destroyed
>>> class C:
def __init__(self):
print("我是init方法,我被调用了")
def __del__(self):
print("我是del方法,我被调用了")
>>> c1 = C()
我是init方法,我被调用了
>>> c2 = c1
>>> c3 = c2
>>> del c3
>>> del c2
>>> del c1
我是del方法,我被调用了
After the object generation, all references to it have been del, will start the garbage collection mechanism
2. arithmetic
Operators | Magic corresponding method | Chinese comments |
---|---|---|
+ | __ add__(self, other) | addition |
- | __ sub__(self, other) | Subtraction |
* | __ mul__(self, other) | multiplication |
/ | __ truediv__(self, other) | True division |
// | __ floordiv__(self, other) | Integer division |
% | __ mod__(self, other) | Modulo division |
divmod(a, b) | __ divmod__(self, other) | Divisor and the remainder the result of combined operations |
** | __ pow__(self, other[,modulo]) | The self other than taking power again modulo |
<< | __ lshift__(self, other) | Bitwise left shift |
>> | __ rshift__(self, other) | Bitwise Right Shift |
& | __ and__(self, other) | Bitwise AND operation |
^ | __ xor__(self, other) | Bitwise XOR operation (the same is 0, 1 iso) |
Shu | __ or__(self, other) | Bitwise OR operation (with a 1) |
Inverse operation method of cube
>>> class Nint(int):
def __radd__(self,other):
return int.__sub__(self,other)
>>> a = Nint(5)
>>> b = Nint(3)
>>> a + b
8
>>> 1 + b
2
>>> #此处执行了3-1,self是3,other是1
3. Simple customization (timer)
import time as t
class MyTimer():
def __init__(self):
self.unit = ['年','月','日','小时','分','秒']
self.prompt = "未开始计时!"
self.lasted = []
self.begin = 0
self.end = 0
# 调用实例直接显示结果
def __str__(self):
return self.prompt
__repr__ = __str__
# 计算两次计时器对象之和
def __add__(self, other):
prompt = "总共运行了"
result = []
for index in range(6):
result.append(self.lasted[index] + other.lasted[index])
if result[index]:
prompt += (str(result[index]) + self.unit[index])
return prompt
# 开始计时
def start(self):
self.begin = t.localtime()
self.prompt = "提示:请先调用stop()停止计时!"
print("计时开始")
# 停止计时
def stop(self):
if not self.begin:
print("提示:请先调用start()进行计时")
else:
self.end = t.localtime()
self._calc()
print("计时结束")
# 内部方法,计算运行时间
def _calc(self):
self.lasted = []
self.prompt = "总共运行了"
for index in range(6):
self.lasted.append(self.end[index] - self.begin[index])
if self.lasted[index]:
self.prompt += (str(self.lasted[index]) + self.unit[index])
# 为下一轮计时初始化变量
self.begin = 0
self.end = 0
print(self.prompt)
>>> t1 = MyTimer()
>>> t2 = MyTimer()
>>> t1.start()
计时开始
>>> t2.start()
计时开始
>>> t1.stop()
总共运行了1分21秒
计时结束
>>> t2.stop()
总共运行了15秒
计时结束
>>> t1
总共运行了1分21秒
>>> t2
总共运行了15秒
>>> t1+t2
'总共运行了1分36秒'
Use perf_counter () and process_time ()
import time as t
class MyTimer:
def __init__(self):
self.prompt = "未开始计时"
self.lasted = 0.0
self.begin = 0
self.end = 0
self.default_timer = t.perf_counter
def __str__(self):
return self.prompt
__repr__ = __str__
def __add__(self,other):
result = self.lasted + other.lasted
prompt = "总共运行了%0.2f秒" % result
return prompt
def start(self):
self.begin = self.default_timer()
self.prompt = "提示:请先调用stop()停止计时"
print("计时开始!")
def stop(self):
if not self.begin:
print("提示:请先调用start()开始计时")
else:
self.end = self.default_timer()
self._calc()
print("计时结束")
def _calc(self):
self.lasted = self.end - self.begin
self.prompt = "总共运行了%0.2f秒" % self.lasted
print(self.prompt)
self.begin = 0
self.end = 0
def set_timer(self,timer):
if timer == 'process_time':
self.default_timer = t.process_time
elif timer == 'perf_counter':
self.default_timer = t.perf_counter
else:
print("输入无效")
t1 = MyTimer()
t1.set_timer('perf_counter')
t1.start()
t.sleep(5.2)
t1.stop()
t2 = MyTimer()
t2.set_timer('perf_counter')
t2.start()
t.sleep(5.2)
t2.stop()
print(t1 + t2)
>>>
计时开始!
总共运行了5.23秒
计时结束
计时开始!
总共运行了5.21秒
计时结束
总共运行了10.44秒
>>>
4. property access
Magic Methods | meaning |
---|---|
__ getattr__(self, name) | When a user attempts to define the behavior of a non-existent property acquired during |
__ getattribute__(self, name) | When the definition of the class property is accessed behavior |
__ setattr__(self, name, value) | When an attribute is defined set of behavior |
__ delattr__(self, value) | Definition of when a property is deleted act |
Avoid attribute magic method of infinite loop:
Using super () calls the base class, a special property __dict__
assignment
class Rectangle:
def __init__(self,width=0,height=0):
self.width = width
self.height = height
def __setattr__(self,name,value):
if name == 'square':
self.width = value
self.height = value
else: #避免死循环的两种方式
# super().__setattr__(name,value)
self.__dict__[name] = value
def getArea(self):
return self.width * self.height
>>> r1 = Rectangle(4,5)
>>> r1.getArea()
20
>>> r1.square = 10
>>> r1.getArea()
100
>>>
The descriptor
Examples of the type of a particular class of attributes assigned to another class of
__get__(self,instance,owner) |
Access to property, the return value of the property |
---|---|
__set__(self,instance,value) |
In the Properties allocation call, do not return anything |
__delete__(self,instance) |
Control delete operation does not return any value |
>>> class Mydecript:
def __get__(self,instance,owner):
print("getting...",self,instance,owner)
def __set__(self,instance,value):
print("setting...",self,instance,value)
def __delete__(self,instance):
print("deleting...",self,instance)
>>> class Test:
x = Mydescript()
Traceback (most recent call last):
File "", line 1, in
class Test:
File "", line 2, in Test
x = Mydescript()
NameError: name 'Mydescript' is not defined
>>> class Test:
x = Mydecript()
#Mydecript是x的描述类
>>> test = Test()
>>> test.x
getting... <__main__.Mydecript object at 0x030EAFB0> <__main__.Test object at 0x03108050>
>>> test.x = "X-man"
setting... <__main__.Mydecript object at 0x030EAFB0> <__main__.Test object at 0x03108050> X-man
>>> del test.x
deleting... <__main__.Mydecript object at 0x030EAFB0> <__main__.Test object at 0x03108050>
Example: temperature conversion
class Celsius:
def __init__(self,value = 26.0):
self.value = float(value)
def __get__(self,instance,owner):
return self.value
def __set__(self,instance,value):
self.value = float(value)
class Fahrenheit:
def __get__(self,instance,owner):
return instance.cel * 1.8 + 32
def __set__(self,instance,value):
instance.cel = (float(value) - 32) / 1.8
class Temperature:
cel = Celsius()
fah = Fahrenheit()
>>> temp = Temperature()
>>> temp.cel
26.0
>>> temp.cel = 30
>>> temp.fah
86.0
>>> temp.fah = 100
>>> temp.cel
37.77777777777778
>>>
6. customized sequence
Example: preparation of a customized list of immutable, required number of records in the list for each element is accessed
class CountList:
def __init__(self,*args):
self.values = [x for x in args]
self.count = { }.fromkeys(range(len(self.values)),0)
def __len__(self):
return len(self.values)
def __getitem__(self,key):
self.count[key] += 1
return self.values[key]
>>> c1 = CountList(1,3,5,7,9)
>>> c1[1]
3
>>> c2 = CountList(2,4,6,8,10)
>>> c2[1]
4
>>> c1[1]+c2[1]
7
>>> c1.count
{0: 0, 1: 2, 2: 0, 3: 0, 4: 0}
>>> c2[1]
4
>>> c2.count
{0: 0, 1: 3, 2: 0, 3: 0, 4: 0}
>>>
7. iterator
Iterator is to achieve the __next__()
object methods can not be rolled back
>>> string = "FishC"
>>> it = iter(string)
>>> next(it)
'F'
>>> next(it)
'i'
>>> next(it)
's'
>>> next(it)
'h'
>>> next(it)
'C'
>>> next(it)
Traceback (most recent call last):
File "", line 1, in
next(it)
StopIteration
>>> string = "FishC"
>>> it = iter(string)
>>> while True:
try:
each = next(it)
except StopIteration:
break
print(each)
F
i
s
h
C
>>> for each in string:
print(each)
F
i
s
h
C
>>>
Example: using an iterator implement Fibonacci number
>>> class Fibs:
def __init__(self,n=10):
self.a = 0
self.b = 1
self.n = n
def __iter__(self):
return self
def __next__(self):
self.a,self.b = self.b,self.a + self.b
if self.a > self.n:
raise StopIteration
return self.a
>>> fibs = Fibs()
>>> for each in fibs:
print(each)
1
1
2
3
5
8