# 1.把一个函数当成另一个函数的返回值
# 2.把一个函数当成另一个函数的参数
# 3.在函数内部定义一个函数 函数的嵌套 外部无法引用函数内部的函数
# 闭包
# 由函数以及相关的引用变量环境组合而成的实体
# 闭包=函数块+引用环境
def outer():
x = 10
def inner():
y = x + 1
return y
return inner
print(outer()())
# 计算一串代码运行的时间
import time # time 模块可以获取当前时间
# 代码运行前获取下时间
# 时间戳是从1970-1-1 00-00-00 UTC 到现在的秒数
# start = time.time() # time 模块里的time方法 可以获取当前时间的时间戳 世界时间
# print('start=',start)
# x = 0
# for i in range(1,10000000):
# x += i
# print(x)
# end = time.time()
# print('代码运行耗时{}秒'.format(end - start))
# time.sleep(3)
# def acl_time(fn):
# start = time.time()
# print('start=',start)
# fn()
# end = time.time()
# print('代码运行耗时{}秒'.format(end - start))
# def foo():
# print('hello')
# time.sleep(10)
# print('world')
# acl_time(foo) # 将一个函数作为另一个函数的参数
# 装饰器的基本使用
import time
def acl_time(fn):
def inner(x,*args,**kwargs): # 传递多个参数
start = time.time()
s = fn(x)
end = time.time()
print('代码耗时',end - start)
return s
return inner # 返回内部函数
@acl_time # 第一件事调用 acl_time;第二件事把被装饰的函数传递给fn
def demo(n):
x = 0
for i in range(1,n):
x += i
return x
# 第三件事 当再次调用demo函数时 这时候的demo函数已经不是上面的了 而是被装饰过的
print(demo(100000,5,7 ))
# @acl_time # 加装饰器
def foo():
print('1')
time.sleep(3)
print('2')
# foo() # 此时的foo 其实是inner
# 如果超过22点不让玩游戏 不给时间就不让玩
# 产品经理 提需求 改需求
def can_play(fn):
def inner(x,y,*args,**kwargs):
clock = kwargs.get('clock',23) # 获取不到 就给默认值 也防止没给参数报错
if clock <= 22:
# if args[0] <= 22:
fn(x,y)
else:
print('太晚了',x,'不能玩',y )
return inner
# 开放封闭原则
# 不更改原来的代码 而去添加需求
@can_play
def play_game(name,game):
print('{}在玩{}'.format(name,game))
play_game('张三','王者',clock=18)
play_game('李四','吃鸡')
# 作业 名片管理系统
all=[]
def all_job():
print('---------------')
print('名片管理系统 v1.0')
print('1:添加名片')
print('2:删除名片')
print('3:修改名片')
print('4:查询名片')
print('5:显示所有名片')
print('6:退出系统')
print('---------------')
input_num = int(input("请输入要进行的操作(数字):"))
if input_num == 1:
# 添加名片 字典的增加
only = {}
name = input('请输入姓名:')
for s in all:
if name in s['name']:
print('用户已存在')
all_job()
only['name'] = name
phone = input('请输入手机号:')
only['phone'] = phone
QQ = input('请输入QQ号:')
only['QQ'] = QQ
all.append(only)
print(all)
all_job()
# 显示所有名片
# 而且如果在添加相同的用户名提示被占用
elif input_num == 2:
num = int(input('请输入要删除的用户序号:'))
del all[num]
all_job()
elif input_num == 3:
pass
num = int(input(' 请输入要修改的序号:'))
print('name:{} phone:{} QQ:{}'.format(all[num]['name'],all[num]['phone'],all[num]['QQ']))
name = input('请输入新的姓名:')
all[num]['name'] = name
phone = input('请输入新的手机号:')
all[num]['phone'] = phone
QQ = input('请输入新的QQ号:')
all[num]['QQ'] = QQ
print(all)
all_job()
elif input_num == 4:
name = input('请输入要查询的姓名:')
for s in all:
if name in s['name']:
print('name:{} phone:{} QQ:{}'.format(s['name'],s['phone'],s['QQ']))
else:
print('用户不存在')
all_job()
# 查询名片 按姓名查
# 找不到提示找不到
# 找到 打印出找到的用户信息
elif input_num == 5:
print('序号 姓名 手机号 QQ')
for i in all:
print(' {} {} {} {}'.format(all.index(i),i['name'],i['phone'],i['QQ']))
all_job()
# 显示所有
elif input_num == 6:
num = input('请确认是否要退出呢(yes/no):')
if num == 'yes' or num == 'y':
exit()
else:
all_job()
# 是否确认退出
# all_job()
# 模块的概念
# 模块:在python里一个py文件 就可以理解为一个模块
# 不是所有的py文件都能作为一个模块导入
# 如果想要让一个py文件可以被导入 模块名字必须遵守命名规则 不能以数字开头
# python 为了让开发方便 提供了很多内置模块
import time # 1.导入time.py 模块
print(time.time()) # 导入之后就可以使用模块里的方法和变量
from random import randint # 2.form 模块名 import 函数名 导入一个模块里的方法或者变量
print(randint(0,2)) # 生成随机数
from math import * # 3.from 模块名 import * 导入这个模块的'所有'方法和变量
print(pi)
import datetime as dt # 4.导入一个模块并起一个别名
print(dt.MAXYEAR)
from copy import deepcopy as dp # 5.form 模块名 import 函数名 as 别名
print(dp([1,2,3,4,]))
# 常见的内置模块
# OS 模块 OperationSystem操作系统
# os 模块提供的方法就是用来调用操作系统里的方法
# os.name() 获取操作系统名字 win nt ----- 其他 posix
# os.sep() 路径分隔符 win \ ---- 其他 /
# path 经常使用
# os.path.abspath() 获取文件的绝对路径
# os.path.isdir() 判断是否是文件夹
# os.path.isfile() 判断是否是文件
# os.path.exists() 判断是否存在
# os.path.splitext() 获取文件的名字
# os.getcwd() 获取当前工作目录
# os.chdir(../) 改变当前脚本工作目录 上级目录
# os.rename('a','b') 文件重命名
# os.remove('a') 删除文件
# os.rmdir('a') 删除空文件夹
# removedirs 删除空文件夹 mkdir 创建文件夹 listdir 列出指定目录的所有
# envison 获取到环境配置
import os
print(os.name)
print(os.sep)
print(os.path.abspath('D:\Python\Python\day06-0723.py'))
print(os.path.isdir('D:\Python\Python\day06-0723.py'))
print(os.path.isfile('D:\Python\Python\day06-0723.py'))
print(os.path.exists('D:\Python\Python\day06-0723.py'))
print(os.path.splitext('D:\Python\Python\2020.txt'))
print(os.getcwd())
os.chdir('D:\Python')
print(os.getcwd())
# os.mkdir('zsssssss')
print(os.listdir(os.getcwd()))
# os.removedirs('zss')
# print(os.listdir(os.getcwd()))
# sys模块 系统相关的功能
# sys.exit() 和内置函数exit() 差不多
# sys.path 查找模块的路径
import sys
# sys.exit() 程序退出
print('111')
# sys.exit()
print('222')
print(sys.path)
# sys.stdin # 可以像input一样 接收用户的输入
# sys.stdout # 修改sys.stdout 可以改变默认的输出位置
# sys.stderr # 修改sys.stdout 可以改变错误输出的默认输出位置
# input('请输入:')
# math模块 数学计算相关的模块
import math
print(math.factorial(6)) # 6的阶乘
print(math.pow(2,10)) # 1024 幂运算 2 ** 10 pow(2,10)
print(math.floor(12.98)) # 12 向下取整
print(math.ceil(12.001)) # 13 向上取整
print(math.sin(math.pi / 2 )) # sin90 弧度 Π = 180°
print(math.cos(math.pi / 2 )) # cos90
print(math.tan(math.pi / 2 )) # tan90
# random模块 用来生成一个随机数
# random.randint(1,3) [1,3]
# random.random() [0,1)的随机浮点数
# random.randrange(2,9) [2,9)的随机整数
# random.choice(['11','22','33','44']) 用来在可迭代对象里随机抽取一个数据
# random.sample(['11','22','33','44'],2) 用来在可迭代对象里随机抽取 n个数据
import random
print(random.randint(1,3)) # 生成a-b的随机数 等价于randrange(a,b+1)
print(random.random()) # [0,1)的随机浮点数
print(random.randrange(2,9))
print(random.choice(['11','22','33','44']))
print(random.sample(['11','22','33','44'],2))
# datetime模块 日期时间模块
import datetime as dt
# datetime.now() 当前日期时间
# date() 创建一个日期
# time() 创建一个时间
# timedelta(3) 3天后
# _x __x __x__
print(dt.datetime.now()) # 当前日期时间
print(dt.date(2020,1,1)) # 创建一个日期
print(dt.time(12,22,33)) # 创建一个时间
print(dt.datetime.now() + dt.timedelta(3)) # 计算3天后的日期时间
# time模块 时间的模块
import time
print(time.time()) # 获取从1970-1-1-00:00 UTC 到现在时间的秒数 时间戳
print(time.strftime('%Y-%m-%d %H:%M:%S')) # 按照指定格式输出
print(time.asctime()) # Fri Jul 24 17:34:13 2020 asctime 传元组
print(time.ctime()) # Fri Jul 24 17:34:13 2020 二者不同之处 传参不一致 ctime 传时间戳
print('2020')
# time.sleep(5) # 暂停5秒
print('2021')
# calendar模块 日历的模块
import calendar
calendar.setfirstweekday(calendar.SUNDAY) # 设置每周起始日期码 周一到周日分别对应0-6
print(calendar.calendar(2020)) # 打印2020年的日历 并以周日为真实日期码
print(calendar.firstweekday()) # 返回当前每周起始日期的设置 默认返回周一 即0
print(calendar.isleap(2021)) # 闰年返回True 否则 False
print(calendar.leapdays(2000,2020)) # 获取从2000到2020一共有多少个闰年
print(calendar.month(2020,7)) # 打印2020年7月份日历
# hashlib模块
# hmac模块
# 都是用来加密的
# hashlib 支持2个算法 md5 和 sha 加密
# 加密方式: 单向加密:只有加密的过程,不能解密(md5/sha) 对称加密 非对称加密ras
# 需要将加密的内容转换为二进制
import hashlib
x = hashlib.md5() # 生成一个md5 对象
x.update('abc'.encode()) # abc ==> 900150983cd24fb0d6963f7d28e17f72
print(x.hexdigest()) # 900150983cd24fb0d6963f7d28e17f72
h1 = hashlib.sha1('123456'.encode())
print(h1.hexdigest()) # 7c4a8d09ca3762af61e59520943dc26494f8941b
h1 = hashlib.sha224('123456'.encode()) # 224位 一个十六进制占4位
print(h1.hexdigest()) # f8cdb04495ded47615258f9dc6a3f4707fd2405434fefc3cbf4ef4e6
h1 = hashlib.sha256('123456'.encode()) # 256位
print(h1.hexdigest()) # 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
h1 = hashlib.sha384('123456'.encode()) # 384位
print(h1.hexdigest()) # 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92
import hmac
# hmac 加密可以指定密钥
import hmac
message = b'Hello world'
key = b'secret'
h = hmac.new(key,message,digestmod='MD5')
print(h.hexdigest())