python学习日记(二)

构造析构,BIF,property,构造MyProperty,new运算符,设计计时器

构造函数:委托构造

在一个类中初始化其它类的init(self[,param1…])函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> class Turtle:
def __init__(self,x):
self.num=x
>>> class Fish:
def __init__(self,y):
self.num=y
>>> class Pool:
def __init__(self,x,y):
self.turtle=Turtle(x)#包含其它类的初始化
self.fish=Fish(y)
def printnum(self):
print("池子里乌龟%d只,鱼%d只" %(self.turtle.num,self.fish.num))

>>> pool=Pool(3,4)
>>> pool.printnum()
池子里乌龟3只,鱼4
1
2
3
4
5
6
7
8
9
10
class C:
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")

一些BIF(内置函数)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> isinstance(pool.fish,Fish)
True
>>> class shark(Fish):
pass
>>> issubclass(shark,Fish)
True
>>> hasattr(pool,'fish')#attribute,属性
True
>>> hasattr(pool,'fish.num')
False
>>> hasattr(pool.fish,'num')
True
>>> getattr(pool.fish,'num')
4
>>> setattr(pool.fish,'num',3)
>>> getattr(pool.fish,'num')
3

x=property(setparameter,getparameter.delparameter

以后可直接更改x的名字而不用改parameter的各个构造函数

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
class example:
def __init__(self,size):
self.size=size
def getsize(self):
return self.size
def setsize(self,x):
self.size=x
def delsize(self):
del self.size
x=property(getsize,setsize,delsize)
#增改删查
>>> exam1=example(10)
>>> exam1.getsize()
10
>>> exam1=example(18)
>>> exam1.getsize()
18
>>> exam1.x#直接访问size
18
>>> exam1.x=99#直接更改size
>>> exam1.x
99
>>> del exam1.x#直接删除size
#官方文档中还可以这样用
class C:
def __init__(self):
self._x = None

@property#修饰符
def x(self):
"""I'm the 'x' property."""
return self._x

@x.setter
def x(self, value):
self._x = value

@x.deleter
def x(self):
del self._x

在example类的基础上,自己设计MyProperty

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
>>> class MyProperty:
def __init__(self=None,fget=None,fset=None,fdel=None):
self.fget=fget
self.fset=fset
self.fdel=fdel
def __get__(self,instance,owner):
return self.fget(instance)#传进来x
def __set__(self,instance,value):
self.fset(instance,value)
def __del__(self,instance):
self.fdel(instance)
运行:
>>> test=example(5)
>>> test.x
5
>>> test.x=3
>>> test.x
3
>>> test.size
3

构造函数 new, init

1
2
3
4
5
6
7
8
9
#__new__, __init__
>>> class CapStr(str):
def __new__(cls,string):
string=string.upper()
return str.__new__(cls,string)

a=CapStr('hello world')
>>> a
'HELLO WORLD'

运算符

算术运算基础,以及子类return的误区

1
2
3
4
5
6
7
8
9
10
11
12
>>> class try_int(int):
def __add__(self,other):
return self+other#报错,相当于在return里接着进行self的加法,死循环
def __sub__(self,other):
return self-other
RecursionError: maximum recursion depth exceeded

>>> class try_int(int):
def __add__(self,other):
return int(self)+int(other)#强制类型转换成父类int就不会报错了
def __sub__(self,other):
return int(self)-int(other)

以下假设变量: a=10,b=20:

表头1 表头2 表头3
+ 两个对象相加 30
- 得到负数或是一个数减去另一个数 -10
* 两个数相乘或是返回一个被重复若干次的字符串 200
/ x除以y 0.5
% 返回除法的余数 0
** 返回x的y次幂 10^20
// 返回商的整数部分(向下取整) 9//2=4,-9//2=-5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
```

## 设计一个计时器

先看下内置函数 __str(print返回str),__repr(直接返回,不需要print

```python
>>> class A():
def __int__(self):
return 5
def __str__(self):
return "佛系青年"

>>> a=A()
>>> print(a)
佛系青年################为什么不管int的返回值呢?
>>> class B():
def __repr__(self):
return "佛系青年"

>>> b=B()
>>> b
佛系青年

基本组成:import time包(localtime,time)init初始化参数,str和repr设定返回的变量,start,stop,calculate计算时间差

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
import time as t

class MyTimer(): # 无父类继承
#各个变量的初始化
def __init__(self):
self.prompt = "未开始计时"
self.lasted = []#tuple数组记录时间差
self.begin = 0#不能和函数名重复
self.end = 0

def __str__(self):
return self.prompt

__repr__ = __str__#???
# 开始计时
def start(self):
self.start = t.localtime()
print('开始计时...')

# 结束计时
def stop(self):
if self.begin==0:
print("请先start()")
self.stop = t.localtime()
self.calculate()
print('计时结束!')

#内部方法,计算运行时间
def calculate(self):
self.lasted = []
self.prompt = '总共运行了:'
#把end和begin忠 年月日时分秒 的差按位依次加到self.lasted的末位
for index in range(6):
self.lasted.append(self.stop[index] - self.start[index])
self.prompt += str(self.lasted[index])
self.prompt+='秒'
print(self.prompt)

运行:
>>> timer=MyTimer()
>>> timer.start()
开始计时...
>>> timer.stop()
总共运行了:000002
计时结束!

重写内置函数__add

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    #用于计算两段时间的和
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])#加上各个单位
print(prompt)

>>> t1=MyTimer()
>>> t1.start()
开始计时...
>>> t1.stop()
总共运行了:000004
计时结束!
>>> t2=MyTimer()
>>> t2.start()
开始计时...
>>> t2.stop()
总共运行了:000003
计时结束!
>>> t1+t2
总共运行了:7

设计一个温度计

实现华氏度与摄氏度的自动转换

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
class Celsius:
def __init__(self,value=26.0):
self.value=value

def __get__(self,instance,owner):
return self.value

def __set__(self,instance,value):
self.value=float(value)

class Fahenheit:
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=Fahenheit()
运行:
>>> temp=Temperature()
>>> temp.cel
26.0
>>> temp.fah
78.80000000000001
>>> temp.fah=183
>>> temp.cel
83.88888888888889
>>> temp.cel=20
>>> temp.fah
68.0