1. 基本语法

python为弱语言类型, 根据赋予的值决定具体数据类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 标准输入输出
name = input("inputyour name")
# sep 为分割符(默认为空格), end 为结束符号(默认为换行符)
print("hi", "im", sep = "-", end = "joke")

# 格式化精度控制
c = 11.5551
print("%d" %c)
print("%.2f" %c) #浮点型输出会自动四舍五入
print("%5.1f" %c)
# 11
# 11.56
# 11.6

a = [1,2,3]
print(type(a))
# <class 'list'>

1.1 基本数据类型

int 类型

无大小限制, 内存许可就无限大

1
2
3
4
5
6
7
print(0b1101) #13 二进制
print(0o734) #476 八进制
print(0x81) #129 16进制

print(bin(21)) # 0b10101
print(oct(21)) # 0o25
print(hex(21)) # 0x15

float 类型

1
2
print(float(130)) #130.0
print(1.3e4) #13000.0

bool 类型

空字符串, 空数组, 空集合均为false

复数类型

1
2
3
4
5
6
7
a = 10 + 3j
print(a)
print(a.real, a.imag)
print(complex(3, 4))
#(10+3j)
#10.0 3.0
#(3+4j)

字符串类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a = "abcd"
#a[0] = "b" # error, not support

for i in a:
print(i)

print(a*3)
print(a+a)
#a
#b
#c
#d
#abcdabcdabcd
#abcdabcd

print(a[0 : 2]) #ab, 切片, [begin : end) , begin默认为0, end默认为字符串长度
print(a[::-1]) #字符串逆转

字符串常用函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
str = "aaBcD 123a"
str.capitalize() #首字母大写
print(str.find("13")) #寻找下标, fail -> -1
print(str.index("1")) #寻找下标, fail -> error
str.lower() #全小写
str.upper() #全大写
print(str.split(" ")) #['aaBcD', '123a'] list列表
print(str.strip("a")) # BcD 123 默认去除两边的空格
print(str) #以上函数的更改只是返回了一个新的字符串, 没有改变真正的对象


a = 10
b = 30
b1 = 40
#f"内容{变量}"
print(f"{a} + {b} = {a+b1}")
print(f"{a-3} + {b} = {a+10}")
# 10 + 30 = 50
# 7 + 30 = 20

部分类型转换函数

1
2
3
4
5
6
7
8
9
10
11
print(int(1.2))      #1
print(chr(77)) #M
print(eval("3 * 9")) #27

x = 10; y = 20
print(eval("x * y")) # 200

a = int(bin(16),2) #16的二进制, 二进制转换为十进制整数
b = int(oct(16),8)
c = int("aB234",16)
print(a, b, c) # 16 16 700980

1.2 基本运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
a = 5; b = 2
print(a**b) #a的b次方
print(a // b) # 2
print(a / b) # 2.5

if a == 5 and b == 2: #true
print(b << 2) #8

if a == 2 or b == 2: #true
print(a >> 1) #2 101 >> 1 == 010


arry=["hi","im","fine","ok"]
print("hi" in arry) #true
print('thank' not in arry) #true

#is 和 is not 判断变量是否引用同一个对象
a = "1"
b = 1
print(a is not b) #true
b = "1"
print(a is b) #true

1.3 基本语句

if 语句

1
2
3
4
5
6
7
8
9
10
# 可以嵌套
a = 10
if a >= 12:
a = 1
elif a == 10:
a = 2
else:
a = 3

print(a) # 2

for, while 语句

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
#乘法表
sum = 0
a = range(1,10)
b = range(1,10)
for i in a:
for j in b:
if i >= j:
sum = i*j
print("%d*%d=%d"%(i,j,sum), end = "\t")
print("\n")

#加法表
pp=0
sum2=0
while pp<=10:
pp+=1
print()
for o in range(1,11):
sum2=pp+o
if pp>=o:
print("%d+%d=%d"%(pp,o,sum2),end=' ')

#else用于for语句
#若for被break打断, 则不进入else
for l in range(1,11):
print(l)
else:
print("for normal end")

2. 数据结构

2.1 list(列表)

有序的可变序列
列表用于存储任意大小的数据集合, 可以是不同数据类型, 包括列表(嵌套)

关于初始化

1
2
3
4
5
6
7
8
9
10
11
12
list=list("like u") #构造函数字符串创建列表
list1=[1,23,4,"i","forever",True] #方括号
list2=[x for x in range(1,11) if x>2] #列表推导式
# ['l', 'i', 'k', 'e', ' ', 'u']
# [1, 23, 4, 'i', 'forever', True]
# [3, 4, 5, 6, 7, 8, 9, 10]

#构造函数初始化list
_list = list((1, 2, 3)) #元组创建列表 [1, 2, 3]
_list = list({1, 2, 3}) # [1, 2, 3]集合创建列表
_list = list({"a" : 1, "b" : 2}) # ['a', 'b'] 字典创建列表
_list = list(x for x in range(1,10) if(x > 5)) # 列表推导式创建列表 [6, 7, 8, 9]

关于列表的访问

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
a = list(x for x in range(1,11))
a.append(11)
a.insert(1, 'x') #下标为1的位置加入'x'
b = list(t for t in range(111,114))
a.extend(b)
#[1, 'x', 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 111, 112, 113]
a.remove('x')
a.pop(len(a) - 1)
del a[a.index(112)]
#[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 111]
print(a.count(1)) #统计元素出现个数 1
a.reverse() #反转
a.sort() #默认正排序
a.sort(reverse=True) #逆排序

print(sorted(a)) #函数返回排序后的对象, 不改变操作对象, 也是默认正排序
print(sorted(a, reverse=True))
a.clear()


#sort函数补充
b = [["a", 15], ["b", 12], ["c", 10]] #拥有子列表的列表

def cmp(x):
return x[1]
b.sort(key=cmp, reverse = True) #通过对比索引为1的元素进行sort, key为指定排序的依据
#[['a', 15], ['b', 12], ['c', 10]]
b.sort(key = lambda y: y[1]) #接受一个参数y 并返回y[1]
#[['c', 10], ['b', 12], ['a', 15]]

c = ['apple','dasdasdas','h1']
c.sort(key = len) #依据len进行排序
# ['h1', 'apple', 'dasdasdas']

k=[1,2,5,3,2,4]
k.sort(key=lambda x:x) #sort函数默认接受返回布尔类型的函数作为参数
k.sort(key=lambda x:-x)
# [1, 2, 2, 3, 4, 5]
# [5, 4, 3, 2, 2, 1]

2.2 tuple(元组)

有序的不可变序列
元组用于存储任意大小的数据集合, 可以是不同数据类型, 包括元组(嵌套)

关于元组的初始化

1
2
3
4
5
6
7
8
9
a=(1) 
b=(1,) #加了逗号, 括号才被理解为元组的()
print(type(a)) #<class 'int'>
print(type(b)) #<class 'tuple'>

t1 = ("aa", )
t1 = tuple("aa")
t1 = (x for x in range(1, 10)) #默认为生成器对象<class 'generator'>
t1 = tuple(x for x in range(1,10))

元组的访问和遍历

简单的for遍历, 可以访问, 但是无法修改和删除, 这也是和列表最大的区别
因此其常用的成员函数较少

  • .count(x)
  • .index(x)
  • .len()

ps: 当元组内放置一个列表, 该子列表可以进行修改

1
2
m=(1,2,3,[4,5,6])
m[3][0]=5

2.3 序列

序列是基本的数据结构, 常见的序列有, 字符串, 元组, 列表

序列的通用操作

切片

1
2
3
4
5
6
7
8
9
10
11
str="0123456789"
# 切片[i:j:k] 操作并不会改变原来的序列, 只是返回一个新序列
# i 表示切片的开始, j 表示切片的结束, k 表示步长, 即打印每隔k步打印一次
print(str[0:len(str)]) # 等价于
print(str[::])

print(str[1:5]) # 1234
print(type(str[1:3])) # <class 'str'>
print(str[4:1:-1]) # i > j 返回一个空序列, 若 k<0 即可配合倒序
str = str[::-1] #因此可以通过这种方式,将序列倒序
str = str[::-1][::-1] #get

连接和复制

1
2
3
4
a = tuple(x for x in range(1,3))
b = tuple(x for x in range(4,6))
c = a + b #(1, 2, 4, 5)
d = a * 3 #(1, 2, 1, 2, 1, 2)

成员检查

1
2
3
d=tuple(x for x in range(1,6))
print(3 in d)
print(11 not in d)

内置函数

1
2
3
4
d=tuple(x for x in range(1,7))
print(len(d)) # 6
print(max(d)) # 6
print(min(d)) # 1

序列的相互转换

1
2
3
4
5
6
7
8
9
10
str="hi"
list_ = list(str)
tuple_ = tuple(str)
tuple_ = list(tuple_) #元组转列表
list_ = tuple(list_) #列表转元组

f = ['h','i',"nine","tse"]
e = ''
print(e.join(f)) # hininetse
print(str(f)) #['h', 'i', 'nine', 'tse']

关于str()函数

1
2
3
4
5
print(str(10))  # 将整数转换为字符串 '10'
print(str(3.14) ) # 将浮点数转换为字符串 '3.14'
print(str([1, 2, 3])) # 将列表转换为字符串 '[1, 2, 3]'
print(str(('a', 'b', 'c'))) # 将元组转换为字符串 "('a', 'b', 'c')"
print(str({'name': 'John', 'age': 25})) # 将字典转换为字符串 "{'name': 'John', 'age': 25}"

2.4 dict(字典)

字典的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#花括号创建字典
a = {"key1" : 1, "key2" : 2} # {'key1': 1, 'key2': 2}
a["key1"] = 2 # {'key1': 2, 'key2': 2}


#函数创建字典
b = [("red",1),("green",3)]
c = dict(b) # {'red': 1, 'green': 3}
c = dict(red = 1, blue = 2) # {'red': 1, 'blue': 2}


#推导式创建字典
p = {x : x * 2 for x in range(1, 6)} # {1: 2, 2: 4, 3: 6, 4: 8, 5: 10}
l = [("red", 1),("green", 3)]
p = {x : j for x, j in l} # {'red': 1, 'green': 3}

字典的更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
map = {"sewerperson" : {"music" : 700, "sex" : "man"}, "nientail" : {"music" : 200, "sex" : "women"}}
map["ninetse"] = {"music" : 0, "sex" : "manman"}

print(map.keys()) #dict_keys(['sewerperson', 'nientail', 'ninetse'])
print(map.values()) #dict_values([{'music': 700, 'sex': 'man'}, {'music': 200, 'sex': 'women'}, {'music': 0, 'sex': 'manman'}])
print(map.items()) #dict_items([('sewerperson', {'music': 700, 'sex': 'man'}), ('nientail', {'music': 200, 'sex': 'women'}), ('ninetse', {'music': 0, 'sex': 'manman'})])

for key in map: #直接遍历key
print(f"key is {key}, value is {map[key]}")
#key is sewerperson, value is {'music': 700, 'sex': 'man'}
#key is nientail, value is {'music': 200, 'sex': 'women'}
#key is ninetse, value is {'music': 0, 'sex': 'manman'}

map.pop("ninetse") #直接清除key and value
del map["nientail"]
#{'sewerperson': {'music': 700, 'sex': 'man'}}

字典的复制和查询函数

1
2
3
4
5
6
7
8
9
10
11
12
13
a = {"k1":1,"k2":9}
print(a.get("k1","404")) # 1
print(a.get("k3")) # None
print(a.get("k3","404")) # 404


a = {"k1":1,"k2":9}
b = a
c = a.copy()
a["k1"] = 2
print(a) # {'k1': 2, 'k2': 9}
print(b) # {'k1': 2, 'k2': 9}
print(c) #{'k1': 1, 'k2': 9}

ps: 字典转为 list , tuple , set 都会只保留 key

2.5 set(集合)

可容纳不同类型
集合的特点是, 无序(元素位置和创建时不一), 不会出现重复元素

集合的创建

1
2
3
4
5
6
7
8
9
10
s1 = {'black', "white", "blue", "blue", 1} # 花括号创建集合 {1, 'blue', 'white', 'black'}
s1 = set("ninetse") # set()函数创建 {'i', 't', 'n', 'e', 's'}

m1 = ['1', 2, 3, 4]
m2 = (1, 2, 3, "2")
s1 = set(m1) # {2, 3, 4, '1'}
s1 = set(m2) # {1, 2, 3, '2'}
s1 = set() # set()

s1 = {i for i in range(1,11)} # 推导式创建 {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

集合的访问: 由于set是无序的, 所以无法用下标访问, 但还是可以用for访问

集合的常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a = {1, 3, 3, 4}
a.add(9) # 添加
a.remove(9) # 移除, 不存在就报错
a.discard(5) # 移除, 不存在返回None
a.pop() #随即移除

b = {2, 9, 5, 3}
print(a.union(b)) #并集 {2, 3, 4, 5, 9}

print(a.difference(b)) # {4}
print(b.difference(a)) # {9, 2, 5}

print(9 in b) # True
print(10 not in b) # True

a.clear() # set()
del a # 直接全删, 若再次调用会直接报错

ps : 在集合中, 还重载了 各类运算符, 如 <=, ==, !=, &(交集), |(并集), -(差集), ^(差集)


3. 函数

在python中, 貌似没有成员函数, 而被称之为方法
函数内部创建的变量为局部变量
函数内部若想修改全局变量, 需要在函数内先将要访问的变量前 + global

1
2
3
4
5
6
7
8
9
def oo(x, y):
print(x, y)
print(oo(1, 4)) # None, 没有返回值的函数

a = 100
def fun():
global a
a+=100
fun()
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
#函数有多个返回值
def func():
return 1,2
x, y = func() # 1 2
print(type(func())) # # <class 'tuple'>

def func1():
return 1,"hello",True
a, b, c = func1() # 1 hello True
print(func1()) # (1, 'hello', True)
print(type(func1())) # <class 'tuple'>

#缺省参数
def func3(x,y,z = 9):
return x + y + z
print(func3(x = 1, y = 2, z = 3))
print(func3(x = 1, y = 2))


# 传入参数的个数不受限制, 以元组的形式接受实参
def funcc(*args):
print(f"args的类型是{type(args)},值是{args}")
funcc(1,2,3,'小明')
# args的类型是<class 'tuple'>,值是(1, 2, 3, '小明')

# 传入参数的个数不受限制, 以字典的形式接受实参
def funccc(**kwargs):
print(f"kwargs的类型是{type(kwargs)},值是{kwargs}")
funccc(key1=1,key2=2)
# kwargs的类型是<class 'dict'>,值是{'key1': 1, 'key2': 2}


#函数作为参数传入函数
a=19;b=20
def compute(x,y):
return x+y
def text(func):
result=func(a,b)+1
return result
compute(a,b) # 39
text(compute) # 40

#lambda定义匿名函数
a=19;b=20
def text(computee):
result=computee(a,b)
return result
text(lambda x,y:x+y) # 39

4. 文件操作

文件读取

1
2
3
4
5
6
7
8
9
10
11
12
def print_file_info(file_name):
f = None
try:
f = open(file_name, "r", encoding = "utf-8")
print(type(f)) # # <class '_io.TextIOWrapper'>
except Exception as reason:
print("open file fail")
else: # 如果未抛出异常会进入else
print(f.read()) #读取文件并打印
finally: # 该部分都会执行
if f:
f.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
f = open("C:/Users/sewerperson/Desktop/intro.cpp","r",encoding = "UTF-8")
print(f.read(2)) #读取n个字符
print(f.readline(5)) # 读取当前行的字符, 若超过当前行字符, 则读取下一行
print(f.readline()) #默认读取当前行所有字符
print(f.readlines(1)) # 读取 n 行封装至列表内, 无参数则把文件每一行都封装 ['\\name\n']

for i in f:
print(i)

print(f.read()) #续着上次未读完的继续
f.close() #关闭文件

with open("C:/Users/sewerperson/Desktop/intro.cpp", "r", encoding = "utf=8") as f:
print(f.readlines())
print(f.read()) # ValueError: I/O operation on closed file.

文件的写操作

1
2
3
4
5
6
7
f=open("C:/Users/sewerperson/Desktop/intro.cpp", "w", encoding = "utf-8") # 如果存在直接覆盖, 不存在就新建
f.write("add") # write 并没有真正写入硬盘中, 而是放置于缓冲区
f.flush() # 直到调用 flush() 或 close() 时, 缓冲区中的内容才真正写入
f.close()

with open("C:/Users/sewerperson/Desktop/intro.cpp", "a", encoding= "utf-8") as f: # 追加
f.write("new")

案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
count = 0
with open("C:/Users/sewerperson/Desktop/intro.cpp", "r", encoding = "utf-8") as f:
for line in f:
w = line.split(" ")
print(w)
for i in w:
if i == "the":
count += 1
print(f"the出现的次数是{count}")


with open("C:/Users/sewerperson/Desktop/intro.cpp", "r",encoding = "UTF-8") as f:
k = f.read()
p = k.split(" ")
print(p.count("the"))
1
2
3
4
5
with open("C:/Users/sewerperson/Desktop/intro.cpp","r",encoding="utf-8") as f:
for line in f:
line.strip()
g = open("xxx.txt", "a", encoding = "utf-8")
g.write(f"{line}")
1
2
3
4
f = open("C:/Users/sewerperson/Desktop/intro.cpp", "r", encoding = "UTF-8")
data=f.read()
data=data.replace("replace me",'')
data=data[:-2] #略去后两个字符

5. 异常

常见异常 :

  • assertionError assert (后面条件为假)
  • attributeError (尝试访问未知的对象属性)
  • index Error (索引超出序列范围)
  • keyError (字典中找到不存在的关键字)
  • osError (操作系统产生的异常)
  • nameError (尝试访问一个不存在的变量)
  • synataxError python (语法错误)
  • typeError (不同类型之间的无效操作)
  • zerodivisionError (除零错误)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
try:
with open("none.txt", "r", encoding = "utf-8") as f:
print(f.read())
except OSError as reason:
print("error ", str(reason)) #error [Errno 2] No such file or directory: 'none.txt'


try:
a=int(input("请输入一个数"))
result=8/a
print(result)
except ValueError as reason: #输入不是数字
print("error ", str(result))
except Exception as reason: #输入0
print("annoymouse error %s"%str(reason))
except Exception as result: #二者都是捕获所有异常, 是等价的
print("some error %s" %result)
except:
print("some error")
else:
print("none error")
finally:
print("dont care error")

异常的传递

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def func1():
print("func1 start")
1/0
print("func1 end")

def func2():
print("func2 start")
func1()
print("func2 end")

def main():
try:
func2()
except Exception as op:
print(op)

main()

# func2 start
# func1 start
# division by zero

6. 模块和包

外部模块的引入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import time #引入模块
time.sleep(10)

from time import sleep # 直接引入模块对应的功能, 只需要模块部分功能
sleep(3)

from time import * # 引入模块所有功能
sleep(3)

from time import sleep as op # 用别名代替功能
op(3)

import time as t
t.sleep(3)

自定义模块和包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#file: app0.py
def add(x, y):
return x + y
def surplus(x, y):
return x - y

#file: app1.py
def add(x, y):
print(x - y)
return x - y
def surplus(x, y):
return x + y
add(9, 1)
if __name__=='__main__': # 只有当程序是直接执行的才会进入
add(1,5)
__all__ = ['add'] #控制那些功能会被导入

#file: app2.py
from pakage.app0 import *
from pakage.app1 import *
print(add(7, 3)) # 8 4 4 后者会覆盖前者, 并且from时模块就开始执行
print(surplus(7, 3)) # 4, 调用的app0, 因为 app1 中使用了 __all__

引入第三方包

1
2
3
4
#国外
pip install 第三方包名
#国内
pip install https://pypi.tuna.tsinghua.edu.cn/simple/ 包名

json包

1
2
3
4
5
6
7
8
9
10
11
12
import json

data = '{"a" : 1, "b" : 2, "c" : 3, "name" : "中文"}'
obj = json.loads(data) # 将json格式的字符串转换为对象, 接受json字符串作为参数
# {'a': 1, 'b': 2, 'c': 3} dict
jsondata = json.dumps(obj) # 将对象转换为json格式的字符串, 返回字符串
readchinese = json.dumps(obj, ensure_ascii = False) #禁用ASCII即可展现中文
#{"a": 1, "b": 2, "c": 3, "name": "\u4e2d\u6587"}
#{"a": 1, "b": 2, "c": 3, "name": "中文"}

with open("C:/Users/sewerperson/Desktop/intro.cpp", "w") as file:
json.dump(obj, file) # 将obj转换为json格式写入 file

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class student:
name = None
sex = "man"
age = 1
__privatemsg = 1980 #私有属性

def __privatefunc(self): #私有方法
print("private func")

def callprivate(self): #公共方法可以调用
self.__privatefunc()
print(self.__privatemsg)

def classfunc(self): #类方法, 必须加入参数 self
print(f"show my name {self.name}")

def __init__(self, name, sex, age): #魔术方法 操控原来的构造方法
self.name = name
self.sex = sex
self.age = age

def __str__(self): #魔术方法 操控原来的str()
return (f"{self.name}, {self.sex}")

def __it__(self, other): #魔术方法, 操控原来的 <
return self.age < other.age

def __le__(self, other): #操控原来的 <=
return self.age <= other.age

def __gt__(self, other): # >
return self.age > other.age

def __ge__(self, other): # >=
return self.age >= other.age

def __eq__(self, other): # ==
return self.age == other.age



student2 = student("tail", "manb", 18) # 构造方法
student3 = student("tail", "woman", 17)
print(student2.__it__(student3)) #False
print(student2 < student3) #False
print(student2 <= student3) #False
print(student2 > student3) #True
print(student2 >= student3) #True
print(student2 == student3) #False
print(str(student2)) #替换原本的str方法 tail, manb

类的继承

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
class phone:
name = "honor"
def ptname(self):
print("im honor")

class phone2022:
name = "huawei"
def ptname(self):
print("im huawei")

class phone2024(phone, phone2022): #同名方法或成员, 左边优先级最高
age = 12
def ptage(self):
print("12 year")

def ptname(self): #同名直接复写
print("im xiaomi")
super().ptname() #默认查找最左边的父类
phone2022.ptname(self) #传参

a = phone2024()
a.ptname()
#im xiaomi
#im honor
#im huawei

多态的简单实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class animal:
def speak(self):
pass
class dog:
def speak(self):
print("bark")
class cat:
def speak(self):
print("mi")

def voice(a : animal):
a.speak()

dog = dog()
cat = cat()
voice(dog)
voice(cat)
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
class airconditioner: #定义抽象类
def make_cool(self):
pass
def make_hot(self): #抽象方法 子类需要复写抽象方法
pass
def swing(self):
print("??? me")
pass

class geli(airconditioner):
def make_cool(self):
print("geli make cool")
def make_hot(self):
print("geli make warm")
#def swing(self):
# print("geli wave")

class meidi(airconditioner):
def make_cool(self):
print("meidi make cool")
def make_hot(self):
print("meidi make warm")
def swing(self):
print("meidi wave")

def makecool(object : airconditioner):
object.make_cool()
def makewarm(object : airconditioner):
object.make_hot()
def swing(object : airconditioner):
object.swing()


airmeidi = meidi()
airgeli = geli()
makecool(airgeli)
makecool(airmeidi)

makewarm(airgeli)
makewarm(airmeidi)

swing(airgeli) # ??? me
swing(airmeidi)

8. 类型注解

类型注解(Type Annotations)为变量、参数、函数返回值等提供了类型信息。
这在代码的可读性, 代码分析和开发工具的支持方面有帮助
但是在运行时, 类型注解不会强制执行, 也不会引发错误

1
2
3
4
5
6
7
8
9
10
def func(a:int, b:str) -> int:
print(a,b)
return a

print(func(3, "hello"))
print(func("hello", 9))
#3 hello
#3
#hello 9
#hello

Union 的使用

1
2
3
4
5
6
7
8
9
10
from typing import Union

mylist : list[Union[int, str]] = [1, "s", "h", 4, 5] # mylist 为 list类型, list内部只有两种类型(int或str)
mydict : dict[Union[int, str], Union[int, str]] = {1 : 2, 1 : "hi", "l" : 1, "i" : "b"}
# mydict 为dict 类型, dict内部可 两种类型 : 两种类型

def useunion(data : Union[int, str]) -> Union[int, str]:
print(data)
return 1
# 传入的参数为 int 或 str类型, 返回也是

9. 进阶功能

9.1 闭包

不定义全局变量, 让函数持续访问或修改一个外部的变量

nonlocal是一个关键字, 用于在嵌套函数中声明一个变量为非局部变量
默认情况下, 内部函数只能读取外部函数的变量, 而不能修改它们
在内部函数中使用nonlocal关键字声明一个变量时
Python会沿着作用域链向上查找, 找到最近的外部函数中具有相同名的变量, 并将其标记为非局部变量
nonlocal关键字只能在嵌套函数中使用,而不能在全局作用域或单独的函数中使用
无需通过定义全局变量,就可以通过函数实现持续访问,操作某个值
闭包使用的变量在函数内,很难被错误的误改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def account_mount(total = 0):
def atm(money, choose = True):
nonlocal total
if choose:
total += money
print(f"put money: +{money}, remain:{total}")
else:
total -= money
print(f"get money: -{money}, remain:{total}")
return atm

atm = account_mount()
atm(100)
atm(100)
atm(100, False)
#put money: +100, remain:100
#put money: +100, remain:200
#get money: -100, remain:100

缺点 : 由于一直持续的引用外部函数的变量,会占用内存

9.2 装饰器

不修改原函数内容情况下为函数添加新功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import time

def outer(sleep):
def inner():
print("now sleep")
sleep()
print("now get up")
return inner

@outer #装饰器 等价于 sleep = outer(sleep)
def sleep():
print("sleeping")
time.sleep(2)

sleep()
#now sleep
#sleeping
#now get up

#若没有装饰器则需要这样写
sheep = outer(sleep)
sheep()

9.3 多线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import threading,time

def sing(song):
while True:
print(f"sing {song}")
time.sleep(1)


def dance(music):
while True:
print(f"dance {music}")
time.sleep(1)

sing = threading.Thread(target = sing, args = ("kk", )) #返回的是Thread对象 , arg要以元组的形式传出
dance = threading.Thread(target = dance, kwargs = {"music" : "msg"}) #kwargs要以字典的形式传出

sing.start()
dance.start()

target: 指定线程要执行的函数或可调用对象 默认是 None
args: 指定传递给 target 的位置参数。默认是 () 元组
kwargs: 指定传递给 target 的关键字参数 默认是 {} 字典
daemon: 指定线程是否是守护线程, 守护线程在主线程结束后会自动终止, 默认是 None, 表示继承主线程的守护状态
name: 指定线程的名字, 默认会生成一个唯一的线程名, 如 Thread-1、Thread-2

9.4 网络编程

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
#server端

import socket
#创建一个socket对象
socket_severe = socket.socket()

#服务端绑定在本机和端口
socket_severe.bind(("localhost", 8888))

#设置服务端允许连接的数量
socket_severe.listen(1)

#等待客户端连接,阻塞语句, 成功链接了才会执行下一句, 返回一个二元元组
client_socket, client_address = socket_severe.accept()
print(f"client address is {client_address}")

while True:
client_msg = client_socket.recv(1024).decode("UTF-8")
#阻塞语句,只有成功链接了才会执行下一句
print(f"client send : {client_msg}")

severe_sentmsg = input("reply to client : ")
client_socket.send(severe_sentmsg.encode("UTF-8"))
if severe_sentmsg == 'exit':
break

client_socket.close()
socket_severe.close()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#client端

import socket
#创建一个socket对象
client_socket=socket.socket()
#客户端连接具体的服务端
client_socket.connect(("localhost",8888))

while True:
sent_data=input("send server is : ")
if sent_data == "exit":
break
client_socket.send(sent_data.encode("UTF-8"))
recv_data = client_socket.recv(1024)
print(f"server reply : {recv_data.decode('UTF-8')}")
client_socket.close()

9.5 正则表达式

正则表达式, 又称规则表达式( Regular Expression), 是使用单个字符串来描述、匹配某个句法规则的字符串
常被用来检索、替换那些符合其个模式(规则)的文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import re # RE模块

str = "python ppypyyp python"
result = re.match("python",str) #match对象实例化, 0索引到len-1索引如果不是 所查找的, 忽略掉后面直接返回none
print(result) #<re.Match object; span=(0, 6), match='python'>
print(result.span()) #(0, 6)
print(result.group()) #python

str = "ppppythonnn pp pythonnn"
result = re.search("python",str) #只找第一个, 失败返回none
print(result) #<re.Match object; span=(3, 9), match='python'>
print(result.span()) #(3, 9)
print(result.group()) #python

result = re.findall("python",str)
print(result) #['python', 'python']

元字符匹配

字符 描述
. 匹配除换行符之外的任何单个字符
[] 匹配[]中列举的字符
\d 匹配任何数字(等同于[0-9]
\D 匹配任何非数字
\w 匹配任何字母数字或下划线字符
\W 匹配任何非字母数字或下划线字符
\s 匹配任何空白字符(空格、制表、换行)
\S 匹配任何非空白字符

数量匹配

字符 描述
* 匹配0次或多次
+ 匹配1次或多次
? 匹配0次或1次
{n} 精确匹配n
{n,} 匹配至少n
{n,m} 匹配至少n次,但不超过m

边界匹配

字符 描述
^ 匹配字符串的开始
$ 匹配字符串的结束
\b 匹配单词边界
\B 匹配非单词边界
\A 匹配整个字符串的开始
\Z 匹配整个字符串的结束

分组匹配

字符 描述
() 用于创建分组
| 匹配左右任意一个表达式

案例

1
2
3
4
5
6
7
8
只能数字和字母, 长度6-10
^[0-9a-zA-Z]{6, 10}$

纯数字, 长度5-11, 第一位不为0
^[1-9][0-9]{4, 10}$

只允许qq,163,gmail三种邮箱地址
^[\w]+(\.[\w-]+)*@(qq|163|gmail)(\.[\w-]+)+$

以上