11月8日总结
python复习
查找python关键字
cmd打开命令提示符窗口,输入python。再输入help(),再输入keywords。
ipython - pip install ipthon (python交互式环境)
一、golbal和nonlocal
Python程序搜索名字的顺序:LEGB
Local —> Embeded —> Global —> Built-in
a = 100
def foo():
# global a
a = 200
def bar():
nonlocal a
a = 300
print(a)
# print(max)
bar()
print(a) #300
foo() #300
print(a) #100
二、一等函数(函数是一等公民)
- 函数可以赋值给变量
- 函数可以作为函数的参数
- 函数可以作为函数的返回值
def is_even(num):
return num % 2 == 0
def square(num):
return num ** 2
nums = [35, 12, 97, 68, 55, 41, 80]
print(list(filter(is_even, nums)))
print(list(map(square, filter(is_even, nums))))
三、抛异常(raise)和捕获异常(except)
import time
class Triangle:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
def create_triangle(a, b, c):
if a + b > c and b + c > a and a + c > b:
return Triangle(a, b, c)
raise ValueError('无效的边长')
create_triangle(1, 2, 5)
file = None
charset = 'gbk'
while True:
try:
file = open('致橡树.txt', 'r', encoding=charset)
data = file.read(1)
except FileNotFoundError:
print('找不到文件,5秒以后重试')
time.sleep(5)
except UnicodeDecodeError:
print('指定了无效的字符集,尝试使用utf-8')
charset = 'utf-8'
else:
while data:
print(data, end='')
time.sleep(0.2)
data = file.read(1)
break
finally:
if file:
file.close()
def fib(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
yield a
obj = fib(20)
while True:
try:
print(next(obj))
except StopIteration:
break
四、练习(Craps赌博游戏)
Craps赌博游戏 ---> 玩家摇两颗色子
如果第一次摇出了7点或11点,玩家胜;如果摇出2点、3点或12点,庄家胜;
如果摇出其他点数,游戏继续,玩家重新摇色子;
如果玩家摇出了第一次摇的点数,玩家胜;如果摇出了7点,庄家胜;
如果摇出其他点数,游戏继续,直到分出胜负。
玩家有1000元,玩家下注玩游戏,赢了就获得下注金额,输了就扣除下注金额,
游戏结束的条件是玩家把钱输光。
from random import randint
money = 1000
while money > 0:
print(f'你的资产是{money}元')
bet = int(input('请下注:'))
if bet > money:
print('你的钱不够,请重新下注')
else:
x1 = randint(1, 6)
y1 = randint(1, 6)
first_point = x1 + y1
if first_point == 7 or first_point == 11:
money += bet
print(f'你第一次的点数是{first_point},你赢了')
elif first_point == 2 or first_point == 3 or first_point == 12:
money -= bet
print(f'你第一次的点数是{first_point},庄家胜利')
else:
print(f'你第一次的点数是{first_point},胜负未分,游戏继续')
while True:
x2 = randint(1, 6)
y2 = randint(1, 6)
current_point = x2 + y2
if current_point == first_point:
money += bet
print(f'您的点数是{current_point},你赢了')
break
elif current_point == 7:
money -= bet
print(f'您的点数是{current_point},庄家胜利')
break
else:
print(f'您的点数是{current_point},胜负未分,游戏继续')
print('你输光了,游戏结束')
# def roll_dice(n=1):
# """摇色子
# :param n: 色子的数量
# :return: 所有色子的点数之和
# """
# total = 0
# for _ in range(n):
# total += random.randrange(1, 7)
# return total
# money = 1000
# while money > 0:
# print(f'你的总资产为: {money}元')
# # 下注金额必须大于0小于等于玩家总资产
# while True:
# debt = int(input('请下注: '))
# if 0 < debt <= money:
# break
# # 第一次摇色子
# first_point = roll_dice(2)
# print(f'\n玩家摇出了{first_point}点')
# if first_point in {7, 11}:
# print('玩家胜!\n')
# money += debt
# elif first_point in {2, 3, 12}:
# print('庄家胜!\n')
# money -= debt
# else:
# game_over = False
# # 第一次摇色子没有分出胜负
# while not game_over:
# # 重新摇色子
# current_point = roll_dice(2)
# print(f'玩家摇出了{current_point}点')
# if current_point == 7:
# print('庄家胜!\n')
# money -= debt
# game_over = True
# elif current_point == first_point:
# print('玩家胜!\n')
# money += debt
# game_over = True
# print('你破产了, 游戏结束!')
五、字符串格式化
path = r'c:\Windows\tea\nice'
print(path)
a, b = 10.123, 5.4321
# format
content = f'{a} + {b} = {a + b:0>10.2f}'
print(content)
message = '\123\75\124\122'
print(message)
name = '\u9a86\u660a'
print(name)
print('hello' * 5)
print('el' in 'hello')
print('hello'[1])
print('hello'[-1])
print('hello'[2:4])
filename = r'c:\Windows\hello.txt'
print(filename.endswith('.txt'))
print('123abc'.isascii())
print('123abc'.isdigit()) #是否只由数字组成
print('123abc'.isalpha()) #是否只由字母组成
print('123abc'.isalnum()) #是否只由数字或字母组成
六、正则表达式
import re
import json
import requests
resp = requests.get('https://www.qq.com/')
html_code = resp.content.decode('gb2312')
pattern = re.compile(r'<a.*?href="(http.+?)".*?>')
iter_obj = re.finditer(pattern, html_code)
for item in iter_obj:
print(item.group(1))
resp = requests.get('https://image.so.com/zjl?ch=beauty&sn=60')
result_dict = json.loads(resp.text)
# result_dict = resp.json()
for elem in result_dict['list']:
print(elem['qhimg_url'])
import re
sentence = 'You go your way, I will go mine!'
words = re.split(r'[,;!.:\s]', sentence)
for index, word in enumerate(words):
print(index, word)
pattern = re.compile(r'[aeiou]', flags=re.I)
print(pattern.sub('#', sentence))
七、练习(双色球)
"""
红色球:1~33 ---> 6 ---> 无放回抽样
蓝色球:1~16 ---> 1
输入N,生成N组随机的双色球号码
"""
import random
N = int(input('请输入N:'))
for i in range(N):
red_list = []
count = 0
while count < 6:
x = random.randrange(1, 34)
if x not in red_list:
red_list.append(x)
count += 1
blue_list = []
y = random.randrange(1, 17)
blue_list.append(y)
red_list.sort()
end_list = red_list + blue_list
for y in end_list[:-1]:
print(f'{y:0>2d}', end=' ')
print(f'+{end_list[-1]:0>2d}')
# def generate_lottery_number():
# red_balls = [num for num in range(1, 34)]
# blue_balls = [num for num in range(1, 17)]
# selected_balls = sorted(random.sample(red_balls, 6))
# selected_balls.append(random.choice(blue_balls))
# return selected_balls
#
#
# def display(balls):
# for ball in balls[:-1]:
# print(f' {ball:0>2d}', end='')
# print(f'+{balls[-1]:0>2d}')
#
#
# for _ in range(10):
# display(generate_lottery_number())
八、集合(底层使用哈希存储,元素必须是hashable类型)
a = {1, 2, 3}
b = {'hello', 'good', 'zoo'}
c = {(1, ), (1, 2), (1, 2, 3)}
print(a)
print(b)
print(c)
# TypeError: unhashable type: 'list'
# d = {[1], [1, 2], [1, 2, 3]}
# print(d)
# TypeError: unhashable type: 'set'
# e = {{1}, {1, 2}, {1, 2, 3}}
# print(e)
# TypeError: unhashable type: 'dict'
# g = {{'A': 15, 'B': 16}, (1, 2), (2, 3)}
# print(g)
注意:集合内不能装列表,不能装集合,不能装字典,可以装元组
九、装饰器
"""
example11 - 装饰器 ---> 装饰一个函数或一个类,为它们提供额外的功能(横切关注功能)。
横切关注(cross-concerning)功能:跟正常的业务没有必然联系,可以动态的添加上或移除掉的功能。
装饰器本身是一个函数,它的参数和返回值也都是函数。
~ 参数:被装饰的函数
~ 返回值:带有装饰功能的函数
"""
import random
import time
def record_time(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f'{func.__name__}执行时间: {end - start:.3f}秒.')
return result
return wrapper
# download = record_time(download)
@record_time
def download(filename):
print(f'开始下载{filename}.')
time.sleep(random.randrange(5, 10))
print(f'{filename}下载完成.')
# upload = record_time(upload)
@record_time
def upload(filename, n_times=1):
print(f'开始上传{filename}.')
for i in range(n_times):
print(f'第{i + 1}次上传: ...')
time.sleep(random.randrange(4, 9))
print(f'{filename}上传完成.')
if __name__ == '__main__':
download('Python从入门到住院.pdf')
download('MySQL从删库到跑路.avi')
upload('《哈利波特》', 2)
十、函数的递归调用
"""
函数的递归调用 ---> 一个函数可以直接或者简接的调用自身
阶乘 ---> n! = n * (n-1)!
"""
import functools
def fac(n):
if n == 0:
return 1
return n * fac(n-1)
print(fac(50))
# def fib(n, temp={}):
# if n in (1, 2):
# return 1
# if n not in temp:
# temp[n] = fib(n-1) + fib(n-2)
# return temp[n]
@functools.lru_cache(maxsize=128) #该装饰器可以帮助缓存中间的数据
def fib(n):
if n in {1, 2}:
return 1
return fib(n-1) + fib(n-2)
for i in range(1, 121):
print(fib(i))
"""
小作业:
一个小孩爬楼梯,他可以一次爬1个,2个或者3个台阶,如果要爬完10个台阶,一共有多少种走法。
"""
# def climb():
# if x+2y+3z==10:
# return (x, y, z)
def climb():
k = 0
for x in range(11):
for y in range(6):
for z in range(4):
if 1*x + 2*y + 3*z == 10:
k += 1
return f'一共有{k}种走法'
print(climb())
十一、locals()和globals()
"""
example13 - locals() / globals()
"""
import os
import sys
message = 'hello, world!'
def foo():
a = 100
b = 'hello'
c = [1, 2, 3]
return locals()
print(foo())
print(globals())
if not os.path.exists('abc/hello'):
os.makedirs('abc/hello')
print(os.environ)
print(os.path.abspath('abc/hello'))
print(sys.version)
print(sys.version_info)
print(sys.getsizeof([1, 2, 3, 4, 5]))
print(sys.getsizeof((1, 2, 3, 4, 5)))
print(sys.getrefcount(message))
a = message
b = message
print(sys.getrefcount(message))
del b
print(sys.getrefcount(message))
del a
print(sys.getrefcount(message))
# Shift + F1 ---> online document ---> Simplified Chinese
十二、使用pillow处理图像
"""
example14 - 使用pillow处理图像
"""
from PIL import Image, ImageFilter
image_obj = Image.open('awaleizi.jpg') # type:Image.Image
# 获取图像的尺寸
print(image_obj.size)
# 得到图像格式
print(image_obj.format)
# 获取图像模式
print(image_obj.mode)
# image_obj.show()
# 滤镜效果
image_obj.filter(ImageFilter.CONTOUR).show()
# 水平翻转
image_obj.transpose(Image.FLIP_LEFT_RIGHT).show()
# 垂直翻转
image_obj.transpose(Image.FLIP_TOP_BOTTOM).show()
# 旋转45度
image_obj.rotate(45).show()
# 生成缩略图
image_obj.thumbnail((500, 300))
image_obj.show()
# 抠图
head = image_obj.crop((472, 15, 894, 202))
head.show()
十三、多线程
"""
example15 - 多线程
"""
from concurrent.futures import ThreadPoolExecutor
from example11 import download, record_time
@record_time
def main():
files = ('aaa.pdf', 'bbb.pdf', 'ccc.xls', 'ddd.ppt')
with ThreadPoolExecutor(max_workers=16) as pool:
for file in files:
pool.submit(download, file)
if __name__ == '__main__':
main()
"""
联网下载图片 ---> 将引起阻塞和等待的耗时间的任务放到单独的线程种执行
"""
import os
from concurrent.futures.thread import ThreadPoolExecutor
import requests
DOWNLOAD_PATH = './images'
def download_picture(picture_url, path):
"""
下载图片
:param picture_url: 图片地址
:param path: 下载路径
"""
filename = picture_url[picture_url.rfind('/') + 1:]
resp = requests.get(picture_url)
if resp.status_code == 200:
full_path = os.path.join(path, filename)
with open(full_path, 'wb') as file:
file.write(resp.content)
def main():
if not os.path.exists('DOWNLOAD_PATH'):
os.makedirs('DOWNLOAD_PATH')
with ThreadPoolExecutor(max_workers=16) as pool:
for page in range(10):
resp = requests.get(f'https://image.so.com/zjl?ch=beauty&sn={page} * 30')
if resp.status_code == 200:
result_dict = resp.json()
for pic_info_dict in result_dict['list']:
picture_url = pic_info_dict['qhimg_url']
pool.submit(download_picture, picture_url, 'DOWNLOAD_PATH')
if __name__ == '__main__':
main()