Python手册
基本数据类型
整数
- Python可以处理"任意"大小的整数,包括负数
- 支持二进制,八进制,十进制,十六进制
前缀 | 例子 | 进制 |
---|---|---|
0b或者0B | a = 0b1010 | 2 |
0o或者0O | a = 0o12 | 8 |
无 | a = 10 | 10 |
0x或者0X | a = 0xa | 16 |
浮点数
-
定义
- a = 1.2
- b = .4
- c = 1.2e-4
-
计算时可能会丢失精度
字符串
- 定义
- a = ’test'
- a = “test”
- a = ‘‘’test’’’
- 可以直接使用单/双引号
1a = "test"
2len(a)
切割字符串
1x = 'hello world'
2# 分割字符串
3a = x.split(' ')
4# ['hello', 'world']
5
6# 合并为字符串
7' '.join(a)
8# 'hello world'
9
10
11# 切片
12s = '12 34'
13s[2:4]
14# ' 3'
格式化字符串
1name = "Akvicor"
2age = 19
3
4# print I'm Akvicor
5new_str = "I'm " + name + ", " + str(age) + " years old"
6print("Case0: " + new_str)
7
8# in python2
9new_str1 = "I'm %s, %d years old" % (name, age)
10print("Case1: " + new_str1)
11
12# in python3
13new_str2 = "I'm {}, {} years old".format(name, age)
14print("Case2: " + new_str2)
15new_str3 = "I'm {names}, {ages} years old".format(
16 names='Akvicor', ages=age
17)
18print("Case3: " + new_str3)
19new_str4 = f"I'm {name}, {age} years old"
20print("Case4: " + new_str4)
21
22# Case0: I'm Akvicor, 19 years old
23# Case1: I'm Akvicor, 19 years old
24# Case2: I'm Akvicor, 19 years old
25# Case3: I'm Akvicor, 19 years old
26# Case4: I'm Akvicor, 19 years old
运算符
+:两个字符串拼接
*****:将字符串重复
布尔型
- True
- False
NONE空值
- 空值就是没有值
- a = ’’ 不叫空
- a = 0 也不叫空
- a = None 叫空
1a = None
2a is None
3# True
4
5a = ''
6a is None
7# False
turtle
- 设置画笔大小
pensize(4)
- 隐藏海龟
hideturtle()
- 切换RGB色彩模式
colormode(255)
- 颜色
color((255, 155, 192), "pink")
- 设置画布宽和高
setup(840, 500)
- 设置画笔速度
speed(10)
turtle peppa pig source code
1"""
2绘制小猪佩奇
3"""
4from turtle import *
5
6
7def nose(x, y):
8 """画鼻子"""
9 # 将海龟移动到指定的坐标
10 goto(x, y)
11 pendown()
12 # 设置海龟的方向(0-东、90-北、180-西、270-南)
13 setheading(-30)
14 begin_fill()
15 a = 0.4
16 for i in range(120):
17 if 0 <= i < 30 or 60 <= i < 90:
18 a = a + 0.08
19 # 向左转3度
20 left(3)
21 # 向前走
22 forward(a)
23 else:
24 a = a - 0.08
25 left(3)
26 forward(a)
27 end_fill()
28 penup()
29 setheading(90)
30 forward(25)
31 setheading(0)
32 forward(10)
33 pendown()
34 # 设置画笔的颜色(红, 绿, 蓝)
35 pencolor(255, 155, 192)
36 setheading(10)
37 begin_fill()
38 circle(5)
39 color(160, 82, 45)
40 end_fill()
41 penup()
42 setheading(0)
43 forward(20)
44 pendown()
45 pencolor(255, 155, 192)
46 setheading(10)
47 begin_fill()
48 circle(5)
49 color(160, 82, 45)
50 end_fill()
51
52
53def head(x, y):
54 """画头"""
55 color((255, 155, 192), "pink")
56 penup()
57 goto(x, y)
58 setheading(0)
59 pendown()
60 begin_fill()
61 setheading(180)
62 circle(300, -30)
63 circle(100, -60)
64 circle(80, -100)
65 circle(150, -20)
66 circle(60, -95)
67 setheading(161)
68 circle(-300, 15)
69 penup()
70 goto(-100, 100)
71 pendown()
72 setheading(-30)
73 a = 0.4
74 for i in range(60):
75 if 0 <= i < 30 or 60 <= i < 90:
76 a = a + 0.08
77 lt(3) # 向左转3度
78 fd(a) # 向前走a的步长
79 else:
80 a = a - 0.08
81 lt(3)
82 fd(a)
83 end_fill()
84
85
86def ears(x, y):
87 """画耳朵"""
88 color((255, 155, 192), "pink")
89 penup()
90 goto(x, y)
91 pendown()
92 begin_fill()
93 setheading(100)
94 circle(-50, 50)
95 circle(-10, 120)
96 circle(-50, 54)
97 end_fill()
98 penup()
99 setheading(90)
100 forward(-12)
101 setheading(0)
102 forward(30)
103 pendown()
104 begin_fill()
105 setheading(100)
106 circle(-50, 50)
107 circle(-10, 120)
108 circle(-50, 56)
109 end_fill()
110
111
112def eyes(x, y):
113 """画眼睛"""
114 color((255, 155, 192), "white")
115 penup()
116 setheading(90)
117 forward(-20)
118 setheading(0)
119 forward(-95)
120 pendown()
121 begin_fill()
122 circle(15)
123 end_fill()
124 color("black")
125 penup()
126 setheading(90)
127 forward(12)
128 setheading(0)
129 forward(-3)
130 pendown()
131 begin_fill()
132 circle(3)
133 end_fill()
134 color((255, 155, 192), "white")
135 penup()
136 seth(90)
137 forward(-25)
138 seth(0)
139 forward(40)
140 pendown()
141 begin_fill()
142 circle(15)
143 end_fill()
144 color("black")
145 penup()
146 setheading(90)
147 forward(12)
148 setheading(0)
149 forward(-3)
150 pendown()
151 begin_fill()
152 circle(3)
153 end_fill()
154
155
156def cheek(x, y):
157 """画脸颊"""
158 color((255, 155, 192))
159 penup()
160 goto(x, y)
161 pendown()
162 setheading(0)
163 begin_fill()
164 circle(30)
165 end_fill()
166
167
168def mouth(x, y):
169 """画嘴巴"""
170 color(239, 69, 19)
171 penup()
172 goto(x, y)
173 pendown()
174 setheading(-80)
175 circle(30, 40)
176 circle(40, 80)
177
178
179def setting():
180 """设置参数"""
181 pensize(4)
182 # 隐藏海龟
183 hideturtle()
184 colormode(255)
185 color((255, 155, 192), "pink")
186 setup(840, 500)
187 speed(10)
188
189
190def main():
191 """主函数"""
192 setting()
193 nose(-100, 100)
194 head(-69, 167)
195 ears(0, 160)
196 eyes(0, 140)
197 cheek(80, 10)
198 mouth(-20, 30)
199 done()
200
201
202if __name__ == '__main__':
203 main()
列表和元组
- 元组是不可变的(Immutable)Python对象,储存在固定的一块内存里
- 列表是可变的(mutable)Python对象,需要两块存储空间,一块固定用来存储实际的列表数据,一块可变的空间用于扩展。
- 结论就是:元组创建和访问要比列表块,但是不如列表灵活
list basic
1a = [1, 2, 3]
2
3b = [1, 'abc', 2.0, ['a', 'b', 'c']]
4
5print(a)
6# [1, 2, 3]
7print(b)
8# [1, 'abc', 2.0, ['a', 'b', 'c']]
9print(a[0])
10# 1
11print(a[0], a[1])
12# 1 2
13# 默认两个之间加入空格
14# 默认分隔符为空格,结尾为换行。但可以修改
15print(a[0], a[1], a[2], sep='*', end='-')
161*2*3-
17
18c = b[1:3]
19print(c)
20# ['abc', 2.0]
21s = 'abcdefghijklmn'
22print(s[3:7], s[-5:-2])
23# defg jkl
list method
1# 获取列表的一些基本信息
2list1 = [9, 1, -4, 3, 7, 11, 3]
3
4print('list1的长度 = ', len(list1))
5
6print('list1里的最大值 = ', max(list1))
7
8print('list1里的最小值 = ', min(list1))
9
10print('list1里3这个元素一共出现了{}次'.format(list1.count(3)))
11
12# 列表复制
13list_copy = list1[:]
14# 不能使用 list_copy = list1 这种方法
15# 这只会让list_copy和list1指向同一个列表
16
17# 列表的改变
18list2 = ['a', 'c', 'd']
19print('list2 = ', list2)
20
21# 给list2结尾添加一个元素'e'
22list2.append('e')
23print('list2 = ', list2)
24
25# 在list2的'a'和'b'之间插入一个'b'
26list2.insert(1, 'b')
27print('list2 = ', list2)
28
29# 删除list2里的 'b' 根据值删除元素
30list2.remove('b')
31print('list2 = ', list2)
32
33# 列表反转
34list3 = [1, 2, 3]
35print('list3 = ', list3)
36list3.reverse()
37print('list3 = ', list3)
38
39# 列表排序
40list4 = [9, 1, -4, 3, 7, 11, 3]
41
42# 永久排序
43list4.sort()
44print('list4 = ', list4)
45list4.sort(reverse=True)
46print('list4 = ', list4)
47# 临时排序
48list4Temp = sorted(list4)
49list4Temp = sorted(list4, reverse=True)
50
51# 删除列表元素 根据位置
52list4 = [9, 1, -4, 3, 7, 11, 3]
53# 是用del删除
54del list4[6] # -> [9, 1, -4, 3, 7, 11]
55# 是用pop()删除 默认是最后一个元素,也可以是指定元素
56p = list4.pop() # -> [9, 1, -4, 3, 7, 11]
57# p = 3
58p = list4.pop(0) # -> [1, -4, 3, 7, 11, 3]
59# p = 9
60
61# ETC
62list5 = [1, 2, 3, 4]
63print(list5 * 2 + [4, 5, 6])
64# [1, 2, 3, 4, 1, 2, 3, 4, 4, 5, 6]
1list1的长度 = 7
2list1里的最大值 = 11
3list1里的最小值 = -4
4list1里3这个元素一共出现了2次
5list2 = ['a', 'c', 'd']
6list2 = ['a', 'c', 'd', 'e']
7list2 = ['a', 'b', 'c', 'd', 'e']
8list2 = ['a', 'c', 'd', 'e']
9list3 = [1, 2, 3]
10list3 = [3, 2, 1]
11list4 = [-4, 1, 3, 3, 7, 9, 11]
12list4 = [11, 9, 7, 3, 3, 1, -4]
13[1, 2, 3, 4, 1, 2, 3, 4, 4, 5, 6]
tuple basic
1# 元组的创建
2
3a = (1, 2, 3)
4b = 1,
5print(a, type(a))
6print(b, type(b))
7
8# 元组的访问
9
10print(a)
11print(a[1])
12print(a[-1])
13print(a[1:3])
14print(a[1:])
15print(a[:2])
tuple methods
元组里面的值与字符串类似,不可以改变
1# 获取元组的一些基本信息
2tuple1 = (9, 1, -4, 3, 7, 11, 3)
3
4print('tuple1的长度 = ', len(tuple1))
5
6print('tuple1里的最大值 = ', max(tuple1))
7
8print('tuple1里的最小值 = ', min(tuple1))
9
10print('tuple1里3这个元素一共出现了{}次'.format(tuple1.count(3)))
11
12tuple5 = (1, 2, 3, 4)
13print(tuple5 * 2 + (4, 5, 6))
1tuple1的长度 = 7
2tuple1里的最大值 = 11
3tuple1里的最小值 = -4
4tuple1里3这个元素一共出现了2次
5(1, 2, 3, 4, 1, 2, 3, 4, 4, 5, 6)
dict basic
1# 字典创建
2
3a = {
4 1: 'a',
5 2: 'b',
6 '3': 'c'
7}
8
9
10# 不可改变的数据类型
11
12l1 = [1, 2, 3]
13# 因为list是可以改变的,所以下面这种是错误的
14# b = {
15# l1: 1
16# }
17
18t1 = (1, 2, 3)
19# 这是可以的,因为tuple不可改变
20c = {
21 t1: l1
22}
23print(c)
24
25
26d = dict()
27print(d)
28
29e = dict(a=1, b=2, d='a')
30print(e)
31
32# 字典的访问
33print(e['d'])
34
35e['c'] = 123
36print(e)
37
38e['c'] = 3
39print(e)
1{(1, 2, 3): [1, 2, 3]}
2{}
3{'a': 1, 'b': 2, 'd': 'a'}
4a
5{'a': 1, 'b': 2, 'd': 'a', 'c': 123}
6{'a': 1, 'b': 2, 'd': 'a', 'c': 3}
dict methods
1d = {
2 'Name': 'Jack',
3 'Age': 9,
4 'Grade': 5
5}
6
7# 不安全,在没有Name时会报错
8print(d['Name'])
9# 在没有Name时输出None
10print(d.get('Name'))
11
12print(d.keys())
13
14print(d.values())
15
16print(d.items())
17
18c = d.pop('Name')
19print(c, d)
20
21d.clear()
22print(d)
23
24
25# 字典的更新
26
27c = {
28 1: 1,
29 2: 2
30}
31print(c)
32c[3] = 3
33c[4] = 4
34
35d = {
36 5: 5,
37 6: 6
38}
39
40# 字典删除 按照键删除
41
42del c[3]
43
44# c.update(d)
45# print(c)
46# 或
47e = {**c, **d}
48print(e)
1Jack
2Jack
3dict_keys(['Name', 'Age', 'Grade'])
4dict_values(['Jack', 9, 5])
5dict_items([('Name', 'Jack'), ('Age', 9), ('Grade', 5)])
6Jack {'Age': 9, 'Grade': 5}
7{}
8{1: 1, 2: 2}
9{1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6}
set basic
1a = {'f', 'a', 'b', 'c'}
2
3print(a)
4
5print('c' in a)
6print('d' in a)
7
8li = [1, 2, 3, 2, 4, 5, 2]
9
10s1 = set(li)
11print(s1, type(s1), list(s1))
1{'a', 'b', 'f', 'c'}
2True
3False
4{1, 2, 3, 4, 5} <class 'set'> [1, 2, 3, 4, 5]
set methods
1s = {1, 2, 3, 4}
2
3s.add(5)
4print(s)
5
6# 如果元素不存在会报错
7s.remove(5)
8# s.remove(5)
9print(s)
10
11a = '123452'
12s1 = set(a)
13print(s1)
14
15
16s1 = {1, 2, 3, 4}
17s2 = {3, 4, 5, 6}
18
19print(s1 & s2)
20print(s1 | s2)
21print(s1 ^ s2)
22print(s1 - s2)
23print(s2 - s1)
1{1, 2, 3, 4, 5}
2{1, 2, 3, 4}
3{'2', '4', '3', '5', '1'}
4{3, 4}
5{1, 2, 3, 4, 5, 6}
6{1, 2, 5, 6}
7{1, 2}
条件语句和循环语句
if elif else
1a = eval(input('Please input a integer: '))
2print('Information: ', a, type(a))
3
4if a > 0:
5 print('This integer is large than 0')
6elif a == 0:
7 print('This integer is equal 0')
8else:
9 print('This integer is smaller than 0')
while
1a = 10
2
3while a > 0:
4 print(a)
5 a -= 1
for
1a = '12345'
2b = [1, 2, 3, 4]
3c = ('a', 'b', 'c', 'd')
4d = {
5 1: 'a',
6 2: 'b',
7 3: 'c'
8}
9e = {1, 2, 3, 4, 9}
10
11for item in a:
12 print(item)
13
14print('\ndict')
15for item in d:
16 print(item)
17for a, b in d.items():
18 print(f'{a}={b}')
19
20print('\nrange')
21for i in range(1, 20, 3): # 默认步长等于1,也可以指定步长,例如三
22 # 等价于 C++ 中的 for(int i = 1; i < 20; i+=3)
23 print(i)
break continue
1for i in range(10):
2 print(i)
3 if i == 3:
4 break
5print('#2')
6for i in range(10):
7 if i % 2 == 0:
8 print(i)
9print('#3')
10for i in range(10):
11 if i % 2 == 0:
12 continue
13 print(i)
10
21
32
43
5#2
60
72
84
96
108
11#3
121
133
145
157
169
Game: guss number
1import random
2
3a = random.randint(0, 100)
4
5while True:
6 num = int(input("Please input your choice: "))
7 if num == a:
8 print('\nCongratulation!')
9 break
10 elif num > a:
11 print('To large')
12 else:
13 print('To small')
14print(f'The number is {a}')
函数
函数的定义和调用
1
2def demo():
3 print('Hello World')
4 print('demo')
5
6
7demo()
8
9
10def demo1(a, b):
11 print(a, b)
12 print('demo1')
13
14
15demo1(a=[1, 2, 3], b={1: 1, 2: 3})
16
17
18def my_sum(a: int, b: int):
19 return a + b
20
21
22print(my_sum(2, 3))
23
24
25def my_max(a):
26 if not a:
27 return None
28 max_value = 0
29 for i in a:
30 if i > max_value:
31 max_value = i
32 return max_value
33
34
35a = [1, 4, 5, 2, 3, 8, 10]
36print(my_max(a))
1Hello World
2demo
3[1, 2, 3] {1: 1, 2: 3}
4demo1
55
610
命名空间和范围
1x = 1
2
3x += 1
4
5print(x)
6
7
8def demo():
9 x = 10
10 print(x)
11
12
13demo()
14
15print(x)
16
17
18def demo1(a):
19 a = a + 10
20 print(a)
21
22
23demo1(a=x)
24
25print(x)
26
27print("Next")
28y = [1, 2, 3]
29print('This is y', y)
30
31
32def demo2(a):
33 a.append(4)
34 print('demo2', a)
35
36
37def demo22(a):
38 a = a + [4]
39 print('demo22', a)
40
41
42demo22(a=y)
43print('After demo22', y)
44demo2(a=y)
45print('After demo2', y)
46print('可以发现这两种方法中 .append() 会影响原数组,而 + 不会影响')
47
48
49
50z = 1
51print('This is z', z)
52
53
54def demo3(a):
55 global z
56 z = z + a
57 print('In function', z)
58
59
60demo3(a=10)
61print('After Function', z)
12
210
32
412
52
6Next
7This is y [1, 2, 3]
8demo22 [1, 2, 3, 4]
9After demo22 [1, 2, 3]
10demo2 [1, 2, 3, 4]
11After demo2 [1, 2, 3, 4]
12可以发现这两种方法中 .append() 会影响原数组,而 + 不会影响
13This is z 1
14In function 11
15After Function 11
可变参数*arge
1def add(a, b):
2 return a + b
3
4
5print(add(1, 2))
6
7
8def add1(a, b, c):
9 return a + b + c
10
11
12print(add1(1, 2, 3))
13
14
15def add2(*args):
16 print(args)
17 result = 0
18 for i in args:
19 result += i
20 return result
21
22
23print(add2(1, 2, 3, 4, 5, 6, 7, 8, 9, 10))
13
26
3(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
455
可变参数**wargs
1def add(**kwargs):
2 print(kwargs)
3
4
5print(add(a=1, b=2))
6
7
8def test(a, b, c):
9 print(a + b + c)
10
11
12def add(x, **kwargs):
13 if x == 2:
14 test(**kwargs)
15
16
17add(x=2, a=1, b=2, c=2)
1{'a': 1, 'b': 2}
2None
35
参数默认值
1def test(a, b=False):
2 if b:
3 return a
4 else:
5 return a * a
6
7
8print(test(3))
9print(test(3, True))
19
23
递归的实现
1def demo(n):
2 result = 1
3 for i in range(1, n+1):
4 result *= i
5 return result
6
7
8def rec(n):
9 if n <= 1:
10 return 1
11 return n * rec(n-1)
12
13
14print(rec(5))
15print(demo(5))
16# 120
17# 120
面向对象
类和对象的基本概念
1class MyClass:
2 pass
3
4
5# __init__() method 方法 function(函数)
6# attribute 属性
7# method 方法
8
9
10class People:
11 def __init__(self, name, age):
12 self.name = name
13 self.age = age
14
15 def say_hi(self):
16 print("Hi, my name is {}, and I'm {}".format(self.name, self.age))
17
18
19someone = People('Jack', 20)
20print(someone.name, someone.age)
21someone.say_hi()
私有属性和受保护属性
保护的属性为变量名前有一个_
,私有属性为变量名前有两个__
。
保护属性可以在类外更改,但IDE会警告
私有属性不可以在类外更改
但是通过某种方法也可以更改私有属性,但并不推荐在类外对这两种属性进行更改
1class People:
2 def __init__(self, name, age):
3 self.name = name
4 self.age = age
5 self._protect_var = 10 # can be replace
6 self.__private_var = 10 # can not be replace
7
8 def say_hi(self):
9 print("Hi, my name is {}, and I'm {}".format(self.name, self.age))
10
11 def get_var(self):
12 return self.__private_var
13
14 def set_var(self, var):
15 self.__private_var = var
16
17
18someone = People('Jack', 20)
19someone.say_hi()
20someone.age = 21
21someone.say_hi()
22someone._protect_var = 30
23print(someone._protect_var)
24
25
26print(someone.get_var())
27someone.set_var(30)
28print(someone.get_var())
29
30# python 只是将私有变量改名,并没有阻止我们对他的访问和修改
31# 这只是变相的阻止我们对他的访问,但在实际项目中请不要这样做
32print(dir(someone))
33someone._People_protect_var = 31
34print(someone._People_protect_var)
35someone._People__private_var = 31
36print(someone.get_var())
1Hi, my name is Jack, and I'm 20
2Hi, my name is Jack, and I'm 21
330
410
530
6['_People__private_var', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_protect_var', 'age', 'get_var', 'name', 'say_hi', 'set_var']
731
831
类的proterty怎么用
@property使类中的私有变量直接以 类名.变量名的形式访问
@变量名.setter 使类中的私有变量直接以 类名.变量名的形式修改(需要先设定变量的property)
此方法可以使私有变量在访问和修改时按照指定的方法进行处理,防止存放进去非法数据
1class People:
2 def __init__(self, name, age, sex):
3 self.__name = name
4 self.__age = age
5 self.__sex = sex
6
7 def say_hi(self):
8 print("Hi, my name is {}, and I'm {}".format(self.__name, self.__age))
9
10 # def get_name(self):
11 # return self.__name
12
13 @property
14 def name(self):
15 return self.__name
16
17 def set_name(self, name):
18 self.__name = name
19
20 def get_age(self):
21 return self.__age
22
23 def set_age(self, age):
24 self.__age = age
25
26 # def get_sex(self):
27 # return self.__sex
28
29 # def set_sex(self, sex):
30 # self.__sex = sex
31
32 @property
33 def sex(self):
34 return self.__sex
35
36 # 必须设置此变量的property
37 @sex.setter
38 def sex(self, sex):
39 self.__sex = sex
40
41
42someone = People(name='Jack', age=20, sex='Male')
43print(someone.get_age())
44someone.set_age(21)
45print(someone.get_age())
46
47print(someone.name)
48
49someone.sex = 'Female'
50print(someone.sex)
继承和多态
1class Animal:
2
3 def eat(self):
4 print('Animal is eating')
5
6
7class Bird(Animal):
8 def sing(self):
9 print('Bird is singing')
10
11 def eat(self):
12 print('Bird is eating')
13
14
15class Dog(Animal):
16 def eat(self):
17 print('Dog is eating')
18
19
20class Cat(Animal):
21 def eat(self):
22 print('Cat is eating')
23
24
25print('Animal')
26a = Animal()
27a.eat()
28print('Bird')
29b = Bird()
30b.eat()
31b.sing()
32print('Dog')
33d = Dog()
34d.eat()
35print('Cat')
36c = Cat()
37print('This is End\n')
38
39
40def demo_eat(a):
41 a.eat()
42
43
44for i in [a, b, c, d]:
45 demo_eat(i)
1Animal
2Animal is eating
3Bird
4Bird is eating
5Bird is singing
6Dog
7Dog is eating
8Cat
9This is End
10
11Animal is eating
12Bird is eating
13Cat is eating
14Dog is eating
type和isinstance的使用
1class A:
2 pass
3
4
5class B(A):
6 pass
7
8
9a = A()
10b = B()
11c = 1
12print('Type A', type(A))
13print('Type B', type(B))
14print('a->A', isinstance(a, A))
15print('c->int', isinstance(c, int))
16print('c->str', isinstance(c, str))
17print('b->B', isinstance(b, B))
18print('b->A', isinstance(b, A)) # 因为B继承自A
类属性和实例属性
类属性在在创建实例时会保留在实例中,修改实例中的属性不回影响到类的属性
但修改类中的属性会影响到后续通过此类实例化出来的实例。
1class Student:
2 count = 0
3
4 def __init__(self, name):
5 Student.count += 1
6 self.name = name
7
8
9s1 = Student('A')
10s2 = Student('B')
11s3 = Student('C')
12print(Student.count)
13
14# print(Student.count)
15# # print(Student.name) 必须有实例才能访问
16# s1 = Student(name='A')
17# print(s1.name)
18# print(s1.count)
19#
20# s1.name = 'B'
21# s1.count = 1
22# print(s1.name)
23# print(s1.count)
24# print(Student.count)
25#
26# Student.count = 2
27# s2 = Student(name='C')
28# print('After change')
29# print(Student.count)
30# print(s1.count)
31# print(s2.count)
10
2A
31
4B
51
61
7After change
83
91
103
类方法和实例方法
类中的普通方法只能先实例化之后,通过实例调用
类中的类方法可以直接调用,不用实例化。类方法因为有cls参数,所以可以调用类中的其他方法(例如静态方法和其他的类方法)
类中的静态方法可以直接调用,不用实例化。
1class People:
2 def __init__(self, name, age):
3 self.name = name
4 self.age = age
5
6 def sayhi(self):
7 print(f"Hi, my name is {self.name}, and I'm {self.age}")
8
9 @classmethod
10 def test1(cls):
11 print('This is a class method')
12 cls.test2() # 因为有cls参数,所以可以调用class方法
13
14 @staticmethod
15 def test2():
16 print('This is a static method')
17
18
19p1 = People(name='Jack', age=20)
20p1.sayhi()
21p1.test1()
22p1.test2()
23print('-------------')
24People.test1()
25People.test2()
模块和包
1# ch8/demo/math.py
2def my_sum(*args):
3 result = 0
4 for i in args:
5 result += i
6 return result
7
8
9def my_max(*args):
10 print("max Value")
11
12
13def my_min(*args):
14 print("min Value")
15
16
17class People:
18 def __init__(self, name, age):
19 self.name = name
20 self.age = age
21
22
23MAX_NUM = 100
24
25
26# print(my_sum(1, 2, 3, 4))
1# ch8/test.py
2import sys
3
4if '/Users/akvicor/Documents/GitHub/Course/LearnCode/Python' not in sys.path:
5 sys.path.append('/Users/akvicor/Documents/GitHub/Course/LearnCode/Python')
6# print(sys.path)
7
8from ch8.demo.math import my_sum
9
10# 只能在pycharm里才不会报错
11# 默认从系统根目录里寻找或从当前目录寻找,pycharm会自动添加ch8设为系统根目录
12print(my_sum(1, 2, 3, 4))
一般在使用import导入包时,最上面一组为系统自带的,中间一组为第三方的,最下面一组为自己的。
Terminal进入venv环境
进入项目目录然后 source venv/bin/activate
if __name__ == “__main__”
直接执行一个文件的时候,这个文件里面的 __name__ 就等于 __main__
否则 __name__
等于文件所在位置
可以使用此语句可以防止此文件被别的文件引用时输出调试信息
pypi
查看包的一些信息
输入输出和文件
print和input本身就是条用了sys,所以我们可以直接使用sys来输入输出
1import sys
2print('Hello World', 'python', sep='%', end='.\n')
3sys.stdout.write('Hello world!\n')
4
5# a = input('ddd: ')
6# print(a, type(a))
7a = sys.stdin.readlines() # command + D to stop
8print(a, type(a))
写入文件,mode默认为r参数
1f = open("test2.txt", mode='w', encoding='utf8')
2
3f.write("line 1\n")
4f.writelines(['This is second line\n', "line 3\n"])
5f.write("测试中文")
6
7f.close()
8
9"""
10参数列表:
11file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True
12
13 ========= ===============================================================
14 Character Meaning
15 --------- ---------------------------------------------------------------
16 'r' open for reading (default)
17 'w' open for writing, truncating the file first
18 'x' create a new file and open it for writing
19 'a' open for writing, appending to the end of the file if it exists
20 'b' binary mode
21 't' text mode (default)
22 '+' open a disk file for updating (reading and writing)
23 'U' universal newline mode (deprecated)
24 ========= ===============================================================
25"""
f为文件指针,当使用readline或readlines的时候指针会向后移动,再次调用时会从指针处继续读,只有用seek将指针改为文件开始处才可以重新从头读
1f = open("test2.txt", encoding='utf-8')
2
3# a = f.read() # while read all line from file, and is very slowly
4# print(a, type(a))
5
6# for line in f: # it will be quickly # only one times for read
7# print(line)
8
9a = f.readline() # while read all line from file, and is very slowly
10b = f.readlines()
11print(a, type(a))
12print(b, type(b))
13
14f.seek(0) # back to first line
15
16
17f.close()
os
1import os
2
3os.getcwd() # 返回一个str,获取当前目录的完整路径
4
5os.listdir() # 返回一个list,包含当前目录里的所有文件和文件夹
6
7os.mkdir('demo') # 创建文件夹
8
9os.path.isdir('demo') # 如果参数是文件夹,返回True
10
11os.chdir('demo') # 进入一个目录
12
13os.path.exists('demo.txt') # 当前目录下有没有这个文件夹或者文件,可以是根目录
14
15os.path.join('ch', 'demo.txt') # 拼接目录,自动添加 '/'
使用pathlib进行文件相关操作
1import os
2from pathlib import Path
3
4# in_file = os.path.join(os.getcwd(), 'demo', 'test.txt')
5#
6# print(in_file)
7#
8# a = Path.cwd() / 'demo' / 'test.txt'
9#
10# print(a)
11# print(type(a))
12#
13# print(a.is_file())
14# print(a.is_dir())
15# print(a.lstat())
16# print(a.parent)
17
18# b = Path.cwd() / 'demo'
19# b = b / 'test'
20# b.rmdir()
21
22p = Path.cwd()
23
24for file in p.glob('*'):
25 print(file)
26
27print('******************************************************************************')
28
29for file in p.rglob('*'):
30 print(file)
读写二进制文件
1a = 'hello world'
2b = b'hello world'
3
4type(a) # <class 'str'>
5type(b) # <class 'bytes'>
6
7
8f = open('test3.txt', 'wb')
9f.write(b'Hello world!')
10f.close()
11
12ff = open('test3.txt', 'rb')
13print(ff.read())
14ff.close()
序列化对象
1import pickle
2
3
4class People:
5 def __init__(self, name, age):
6 self.name = name
7 self.age = age
8
9 def sayhi(self):
10 print("Hi, my name is {}, and I'm {}".format(self.name, self.age))
11
12
13p1 = People(name='Akvicor', age=20)
14f = open('p1', 'wb')
15pickle.dump(p1, f)
16f.close()
17
18
19# 测试序列化对象的加载 (需要类的原型去映射)
20
21fp = open('p1', 'rb')
22p2 = pickle.load(fp)
23f.close()
24print(p2)
函数式编程
- 高阶函数是至少满足下列一个条件的函数
- 接受一个或多个函数作为输入
- 输出一个函数
1print(sum([1,2,3]))
2b = sum
3print(b([1,2,3])) # 因为sum是一个函数,所以b被赋值为sum后,b也是个函数,功能与sum相同
4def test(x, f):
5 return f(x)
6printf(test([1,2,3], sum)) # 因为传入的函数为sum, 所以功能为求和
7printf(test([1,2,3], max)) # 因为传入的函数为max, 所以功能为求最大值
8# test就是一个高阶函数
lambda 匿名函数
1def test(x, y):
2 return x + 2 * y
3
4
5f = lambda x, y: x + 2 * y
6
7print(test(1, 2))
8print(f(1, 2))
9
10
11def demo(x, y, f):
12 return f(x, y)
13
14
15print(demo(1, 2, lambda x, y: x + 2 * y))
16
17
18def add_n(n):
19 return lambda x: n + x
20
21
22f = add_n(40)
23print(f(1))
24print(f(-10))
列表解析
1a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
2
3b = [item**2 for item in a if item % 2 == 0]
4
5print(b)
6
7# 列表解析
8
9# 字典解析
高阶函数map和reduce
1from functools import reduce
2
3a = [1, 2, 3, 4]
4
5# def f(x, y):
6# return x + y
7
8
9m = map(lambda x: x * x, a)
10
11for i in m:
12 print(i)
13
14
15r = reduce(lambda x, y: x + y, a)
16
17print("r ", r)
filter
1a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
2
3f = filter(lambda x: x % 2 == 1, a)
4print(f)
5for i in f:
6 print(i, end=' ')
7
8print("\nlist")
9
10ff = [i for i in a if i % 2 == 1]
11print(ff)
decorator
1def test1(x):
2 # print(test1.__name__)
3 return x * 2
4
5
6def test2(x):
7 # print(test2.__name__)
8 return x**3
9
10
11test1(1)
12test2(2)
13
14
15def demo(f):
16 def f_new(x):
17 print(f.__name__)
18 return f(x)
19 return f_new
20
21
22f = demo(test1)
23
24print(f(3))
25
26
27# 装饰器
28
29@demo
30def test3(x):
31 return x * 2 * x
32
33
34print("for the test3")
35a = test3(4)
36print(a)
37
38
39@demo
40def test3(x):
41 print('hello world')
42
43
44print('After @@')
45test3(1)
完善装饰器
主要是文档注释等函数属性问题
1import functools
2
3
4def demo(f):
5 """
6 This is f
7 :param f:
8 :return:
9 """
10 @functools.wraps(f) # 解决文档注释问题
11 def f_new(*args, **kwargs):
12 """
13 This is f-new
14 :param args:
15 :param kwargs:
16 :return:
17 """
18 print(f.__name__)
19 return f(*args, **kwargs)
20 # 解决文档注释问题, 或者使用functiontools解决
21 # f_new.__name__ = f.__name__
22 # f_new.__doc__ = f.__doc__
23 return f_new
24
25
26@demo
27def test1(x, y):
28 """
29 This is test 1
30 :param x: integer
31 :param y: integer
32 :return: str
33 """
34 print(f'x={x}, y{y}')
35
36
37test1(1, 2)
38
39print(test1.__name__)
40print(test1.__doc__)
异常和处理
1a = [10, 4, 3, 7, 11, 6, 0, 9, 22, 'c']
2try:
3 b = [item for item in a if 100 % item == 0]
4 print(b)
5except ZeroDivisionError:
6 print('Zero Error')
7except TypeError:
8 print('Type Error')
9except Exception as e:
10 print('Other', e)
11
12print('Finished')
自定义异常
1class MyException(Exception):
2 pass
3
4
5# raise MyException("This is user defined exception")
6
7try:
8 raise MyException("This is user defined exception")
9except MyException as e:
10 print(e)
assert
1def demo(x, y):
2 return x + y
3
4
5print(demo(1, 2))
6assert(demo(1, 2) != 3)
try-except-else
1try:
2 # 执行代码
3except:
4 # 如果有异常发生,执行此处代码
5else:
6 # 如果没有异常发生,执行此处代码
try-except-else-finally
1try:
2 # 执行代码
3except:
4 # 如果有异常发生,执行此处代码
5else:
6 # 如果没有异常发生,执行此处代码
7finally:
8 # 不管有没有异常都会执行此处代码
调试和测试
print 调试
pdb 调试
1import pdb
2
3pdb.set_trace()
PyCharm Debug
doc test
适合小型的项目
1def func_demo(a, b):
2 """ doc test demo
3 >>> func_demo(1, 2)
4 3
5 >>> func_demo('a', 'b')
6 'ab'
7 >>> func_demo([1, 2], [3, 4])
8 [1, 2, 3, 4]
9 >>> func_demo(1, '2')
10 Traceback (most recent call last):
11 TypeError: unsupported operand type(s) for +: 'int' and 'str'
12 >>>
13 """
14 return a + b
15
16
17if __name__ == "__main__":
18 import doctest
19 doctest.testmod()
单元测试
Python单元测试规范
- 测试都是以class形式定义
- 每一个测试类都必须是 unittest.TestCase 的子类
- 每一个测试类里的测试方法都必须以 test_ 开头
- 使用 assert 去检查预期结果和实际结果是否相符
- 在测试方法运行之前需要使用 setUp() 方法预先定义一些测试规范和临时变量
- 在测试方法执行完之后需要使用 tearDown() 方法清理和销毁临时变量等测试环境
- 使用 python -m unittest -v test_module 执行测试
unittest
1import unittest
2
3from demo.math import add
4
5
6class TestAdd(unittest.TestCase):
7 def test_add(self):
8 self.assertEqual(add(1, 4), 5)
9
10 def test_add2(self):
11 self.assertEqual(add(10, 20), 30)
12 self.assertNotEqual(add(10, 20), 31)
13
14 def test_add3(self):
15 self.assertRaises(ValueError, add, 1, 1.2)
16
17
18if __name__ == '__main__':
19 unittest.main()
pysnooper
pip install pysnooper
1import pysnooper
2
3@pysnooper.snoop()
4def f(a, b):
5 return a + b
6
7
8f(1, 2)
logging 模块
1"""
2low -> high
3debug(), info(), warning(), error(), critical()
4"""
5import logging
6
7logging.basicConfig(level='INFO')
8
9logging.debug('This is debug')
10logging.info('This is info')
11logging.warning('This is warning')
12logging.error('This is error')
13logging.critical('This is critical')
文件写入
1"""
2low -> high
3debug(), info(), warning(), error(), critical()
4"""
5import logging
6
7logging.basicConfig(level='INFO', filename='test.log', filemode='w') # w 重新生成文件,默认在文件结尾添加内容
8
9logging.debug('This is debug')
10logging.info('This is info')
11logging.warning('This is warning')
12logging.error('This is error')
13logging.critical('This is critical')
logging format
1"""
2https://docs.python.org/3/library/logging.html#logrecord-attributes
3"""
4import logging
5
6format = '%(asctime)s-%(funcName)s-%(lineno)d-%(levelname)s %(name)s %(message)s'
7
8logging.basicConfig(level='INFO', format=format)
9# logging.BASIC_FORMAT
10
11
12def main():
13 logging.debug('this is debug')
14 logging.info('this is info')
15 logging.warning('this is warning')
16 logging.error('this is erro')
17 logging.critical('this is critical')
18
19
20if __name__ == "__main__":
21 main()
创建新的logging对象
1import logging
2
3logger = logging.getLogger(name='demo')
4logger.setLevel(logging.DEBUG)
5
6# Create handlers
7c_handler = logging.StreamHandler()
8f_handler = logging.FileHandler('file.log')
9c_handler.setLevel(logging.DEBUG)
10f_handler.setLevel(logging.INFO)
11
12# Create formatters and add it to handlers
13c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
14f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
15c_handler.setFormatter(c_format)
16f_handler.setFormatter(f_format)
17
18# Add handlers to the logger
19logger.addHandler(c_handler)
20logger.addHandler(f_handler)
21
22
23def main():
24 logger.debug('this is debug')
25 logger.info('this is info')
26 logger.warning('this is warning')
27 logger.error('this is erro')
28 logger.critical('this is critical')
29
30
31if __name__ == '__main__':
32 main()
pypy提高python代码执行效率
bin目录下为可执行文件
测试代码
1import time
2
3
4def test():
5 for i in range(1, 10):
6 n = pow(10, i)
7 start_time = time.time()
8 sum(x for x in range(1, n+1))
9 end_time = time.time()
10 print(f'10^{i}:{end_time-start_time}')
11
12
13test()
Normal
110^1:3.0994415283203125e-06
210^2:8.106231689453125e-06
310^3:6.008148193359375e-05
410^4:0.0006120204925537109
510^5:0.006687164306640625
610^6:0.06196117401123047
710^7:0.49938416481018066
810^8:4.975664854049683
910^9:49.28339099884033
PyPy
110^1:1.811981201171875e-05
210^2:6.198883056640625e-05
310^3:0.0033159255981445312
410^4:0.00019216537475585938
510^5:0.001216888427734375
610^6:0.0063250064849853516
710^7:0.05159306526184082
810^8:0.5082838535308838
910^9:5.0509021282196045
除另有声明外,本博客文章均采用 知识共享 (Creative Commons) 署名 4.0 国际许可协议 进行许可。转载请注明原作者与文章出处。