day11 回顾
函数式编程
函数的可重入性:
输入一定,结果必然一定
在函数内部不能访问除局部变量以外的变量
高阶函数 hight order function
map(func, 可迭代对象1, 可迭代对象2, ...)
filter(func, 可迭代对象)
sorted(可迭代对象, key=None, reverse=False)
def key_func(可迭代对象内的元组):
return 值(用比较的依据)
递归函数
缺点:
层数太多的递归可能会引起运行的不确定性
闭包:
闭包是指引用了外部嵌套函数作用域内变量的函数(内嵌函数)
闭包的特点:
当内嵌函数引用了外部嵌套函数作用域的变量时(外部嵌套函数的变量
不会被释放)
闭包的三个条件:
1. 有内嵌函数
2. 内嵌函数要引用外部嵌套函数的变量
3. 外部函数要返回内嵌函数
day12 笔记
装饰器 decorators(专业提高篇)
什么是装饰器
装饰器是一个函数,主要作用是用来包装另一个函数或类(后面才讲)
作用:
在不修改被装饰函数的源代码,不改变被装饰函数的调用方式的情况
下添加或改变函数的功能
函数装饰器的语法:
def 装饰器函数名(fn):
语句块
return 函数对象
@装饰器函数名<换行>
def 被装饰函数名(形参列表):
语句块
示例见:
mydeco1.py
mydeco2.py
mydeco3.py
1 # mydeco1.py 2 3 4 # 此示例示意装饰器的原理和语法 5 def mydeco(fn): 6 def fx(): 7 print("++++++++++++++++++") 8 fn() 9 print("------------------") 10 return fx 11 12 def myfunc(): 13 '''被装饰函数''' 14 print("函数myfunc被调用!") 15 16 myfunc = mydeco(myfunc) # myfunc 绑定fx 17 18 myfunc() 19 myfunc() 20 myfunc() 21
1 # mydeco1.py 2 3 4 # 此示例示意装饰器的原理和语法 5 def mydeco(fn): 6 def fx(): 7 print("++++++++++++++++++") 8 fn() 9 print("------------------") 10 return fx 11 12 13 @mydeco 14 def myfunc(): 15 '''被装饰函数''' 16 print("函数myfunc被调用!") 17 18 # myfunc = mydeco(myfunc) # 上面的@mydeco 等同于此句 19 20 myfunc() 21 myfunc() 22 myfunc() 23
1 # mydeco3.py 2 3 # 此示例示意函数装饰器的使用 4 # 以银行存取款业务为例,来为存取款业务添加新的功能 5 # 1. 添加了权了限验证 6 # 2. 添加短消息提醒 7 8 # -------以小钱写的装饰器------------ 9 def privileged_check(fn): 10 def fx(n, x): 11 print("正在检查权限.....") 12 fn(n, x) 13 return fx 14 15 def send_message(fn): 16 def fy(n, x): 17 fn(n, x) 18 print("正在发短消息给:", n) 19 return fy 20 21 # -------以下是魏老师写的程序--------- 22 @privileged_check 23 def savemoney(name, x): 24 print(name, '存钱', x, '元') 25 26 @send_message 27 @privileged_check 28 def withdraw(name, x): 29 print(name, '取钱', x, '元') 30 31 # ------以下是调用者小张写的程序------- 32 savemoney('小王', 200) 33 savemoney('小赵', 400) 34 35 withdraw('小李', 500) 36 37 38
函数的文档字符串:
函数内第一次未赋值给任何变量的字符串是此函数的方档字符串
函数的文档字符串可以用 >>> help(函数名) 查看
语法:
def 函数名(参数列表):
'函数的文档字符串'
语句块
示例:
def myfunc(a, b, c=0):
'''这是myfunc函数的方档字符串
参数:
a 代表xxx
b 代表yyy
...
'''
pass
说明:
文档字符串通常用来说明本函数的功能,使用方法和形参列表
函数的文档字符串绑定在函数的 __doc__属性上
函数的 __doc__ 属性
__doc__属性用于绑定函数的文档字符串
函数的 __name__属性
__name__属性用来记录函数名
注:
以双下划线开头,以双下划线结尾的标识符通常代表python的特殊
变量
示例:
def fabc():
pass
fn = fabc
print(fn.__name__) # 'fabc'
print(fabc.__name__) # 'fabc'
函数定义语句(def 语句)的完整语法:
[@装饰器名1]
[@装饰器名2]
[...]
def 函数名([位置形参], [*元组形参], [命名关键字形参],
[**字典形参]):
'文档字符串'
语句块
注:
[] 代表其中的内容可省略
面试题:
L = [1, 2, 3]
def f(n=0, lst=[]):
''' 缺省参数[]在def语句执行时就已经创建该列表,并一直被
f函数绑定'''
lst.append(n)
print(lst)
f(4, L) # [1, 2, 3, 4]
f(5, L) # [1, 2, 3, 4, 5]
f(100) # [100]
f(200) # [100, 200] # ???
请问打印结果是什么? 为什么?
解决办法:
L = [1, 2, 3]
def f(n=0, lst=None):
if lst is None:
lst = [] # 创建一个新的空列表
lst.append(n)
print(lst)
f(4, L) # [1, 2, 3, 4]
f(5, L) # [1, 2, 3, 4, 5]
f(100) # [100]
f(200) # [200] # 此函数可重入
1 L = [1, 2, 3] 2 def f(n=0, lst=None): 3 if lst is None: 4 lst = [] # 创建一个新的空列表 5 lst.append(n) 6 print(lst) 7 8 f(4, L) # [1, 2, 3, 4] 9 f(5, L) # [1, 2, 3, 4, 5] 10 f(100) # [100] 11 f(200) # [200] 12 13
模块 Module
什么是模块:
模块是一个包含有一系列数据,函数,类等组成的程序组
模块是一个文件,模块文件通常以.py结尾
作用:
1. 让一些相关的数据,函数,类等有逻辑的组织在一起,使逻辑结
构更加清晰
2. 模块中的数据,函数和类等可提供给其它模块或程序使用
模块的分类:
1. 内置模块,在解析器的内部可以直接使用(一般用C语言编写)
2. 标准库模块,安装python时已安装且可直接使用
3. 第三方模块(通常为开源,需要自己安装)
安装命令:
$ pip3 install 模块名
4. 用户自己编写的模块(可以作为其它人的第三方模块)
模块的导入语句:
import 语句
语法:
import 模块名1 [as 模块新名1], 模块名2 [as 模块新名2],...
示例:
import math
import sys, os
import tensorflow as tf
作用:
将某模块整体导入到当前模块中
用法:
模块名.属性名
如:
import math
math.factorial(5)
dir(obj) 函数,返回模块中所有属性的字符串列表
help(obj) 函数,可以查看模块的相关文档字符串
>>> dir(math)
>>> help(math)
练习:
1. 输入一个圆的半径,打印出这个圆的面积
2. 输入一个圆的面积,打印出这个圆的半径
(要求用math模块里的函数和数据)
1 # 面积 = 圆周率 * 半径**2 2 # 半径 = math.sqrt(面积/圆周率) 3 4 5 # 练习: 6 # 1. 输入一个圆的半径,打印出这个圆的面积 7 import math # 导入math模块 8 r = float(input("请输入圆的半径: ")) 9 area = math.pi * r ** 2 10 print("半径为:", r, '的圆的面积是:', area) 11 12 # 2. 输入一个圆的面积,打印出这个圆的半径 13 area2 = float(input("请输入圆的面积: ")) 14 r2 = math.sqrt(area2 / math.pi) 15 print('面积为: ', area2, '的圆的半径是:', r2) 16 17 18
1 # 面积 = 圆周率 * 半径**2 2 # 半径 = math.sqrt(面积/圆周率) 3 4 5 # 练习: 6 # 1. 输入一个圆的半径,打印出这个圆的面积 7 import math as m 8 9 r = float(input("请输入圆的半径: ")) 10 area = m.pi * r ** 2 11 print("半径为:", r, '的圆的面积是:', area) 12 13 # 2. 输入一个圆的面积,打印出这个圆的半径 14 area2 = float(input("请输入圆的面积: ")) 15 r2 = m.sqrt(area2 / m.pi) 16 print('面积为: ', area2, '的圆的半径是:', r2) 17 18 19
1 # 面积 = 圆周率 * 半径**2 2 # 半径 = math.sqrt(面积/圆周率) 3 4 5 # 练习: 6 # 1. 输入一个圆的半径,打印出这个圆的面积 7 from math import pi, sqrt 8 9 r = float(input("请输入圆的半径: ")) 10 area = pi * r ** 2 11 print("半径为:", r, '的圆的面积是:', area) 12 13 # 2. 输入一个圆的面积,打印出这个圆的半径 14 area2 = float(input("请输入圆的面积: ")) 15 r2 = sqrt(area2 / pi) 16 print('面积为: ', area2, '的圆的半径是:', r2) 17 18 19
from import 语句
语法:
from 模块名 import 模块属性名1 [as 属性新名1], 模块属
性名2 [as 属性新名2], ...
作用:
将某模块内的一个或多个属性导入到当前模块的作用域
示例:
from math import factorial as fac
from math import sin
from math import pi, sqrt
print(pi/2)
print(fac(5))
from import *语句
语法:
from 模块名 import *
作用:
将某模块的所有属性导入到当前模块
示例:
from math import *
sin(pi/2)
factorial(5)
dir 函数:
dir([对象]) 返回一个字符串列表
参数说明
如果没有参数调用,则返回当前作用域内所有变量的列表
如果给定一个对象作为参数,则返回这个对象的所有变量的列表
对于一个模块,返回这个模块的全部变量
对于一个类对象,返回类对象的所有变量,并递归基类对象的所有变量
对于其它对象返回所有变量,类变量和基类变量
数学模块:
文档参见:
python_base_docs_html/数学模块math.html
数学模块用法:
import math # 或 from math import *
变量
描述
math.e
自然对数的底e
math.pi
圆周率pi
函数名
描述
math.ceil(x)
对x向上取整,比如x=1.2,返回2
math.floor(x)
对x向下取整,比如x=1.2,返回1
math.sqrt(x)
返回x的平方根
math.factorial(x)
求x的阶乘
math.log(x[, base])
返回以base为底x的对数, 如果不给出base,则以自然对数e为底
math.log10(x)
求以10为底x的对数
math.pow(x, y)
返回 x**y (x的y次方)
math.fabs(x)
返回浮点数x的绝对值
角度和弧度degrees互换
math.degree(x)
将弧度x转换为角度
math.radians(x)
将角度x转换为弧度
三角函数
math.sin(x)
返回x的正弦(x为弧度)
math.cos(x)
返回x的余弦(x为弧度)
math.tan(x)
返回x的正切(x为弧度)
math.asin(x)
返回x的反正弦(返回值为为弧度)
math.acos(x)
返回x的反余弦(返回值为为弧度)
math.atan(x)
返回x的反正切(返回值为为弧度)
时间模块
文档参见:
python_base_docs_html/时间模块time.html
1 时间模块 time 2 此模块提供了时间相关的函数,且一直可用 3 时间简介 4 公元纪年是从公元 0000年1月1日0时开始的 5 6 计算机元年是从1970年1月1日0时开始的,此时时间为0,之后每过一秒时间+1 7 8 UTC 时间 (Coordinated Universal Time) 是从Greenwich时间开始计算的. 9 UTC 时间不会因时区问题而产生错误 10 11 DST 阳光节约时间(Daylight Saving Time),又称夏令时, 是一个经过日照时间修正后的时间 12 13 时间元组 14 时间元组是一个9个整型元素组成的,这九个元素自前至后依次为: 15 四位的年(如: 1993) 16 月 (1-12) 17 日 (1-31) 18 时 (0-23) 19 分 (0-59) 20 秒 (0-59) 21 星期几 (0-6, 周一是 0) 22 元旦开始日 (1-366) 23 夏令时修正时间 (-1, 0 or 1). 24 注: 25 如果年份值小于100,则会自动转换为加上1900后的值 26 模块名: time 27 时间模块用法: 28 import time 29 # 或 30 from time import xxx 31 # 或 32 from time import * 33 变量 描述 34 time.altzone 夏令时时间与UTC时间差(秒为单位) 35 time.daylight 夏令时校正时间 36 time.timezone 本地区时间与UTC时间差(秒为单位) 37 time.tzname 时区名字的元组, 第一个名字为未经夏令时修正的时区名, 38 第一个名字为经夏令时修正后的时区名 39 注: CST为中国标准时间(China Standard Time UTC+8:00) 40 41 函数名 描述 42 time.time() 返回从计算机元年至当前时间的秒数的浮点数(UTC时间为准) 43 time.sleep(secs) 让程序按给定秒数的浮点数睡眠一段时间 44 time.gmtime([secs]) 用给定秒数转换为用UTC表达的时间元组 45 (缺省返回当前时间元组) 46 time.asctime([tuple]) 将时间元组转换为日期时间字符串 47 time.mktime(tuple) 将本地日期时间元组转换为新纪元秒数时间(UTC为准) 48 time.localtime([secs]) 将UTC秒数时间转换为日期元组(以
练习:
写一个程序,输入你的出生日期(年月日)
1) 算出你已经出生了多少天?
2) 算出你出生那天是星期几?
1 # 练习: 2 # 写一个程序,输入你的出生日期(年月日) 3 # 1) 算出你已经出生了多少天? 4 # 2) 算出你出生那天是星期几? 5 6 import time 7 8 y = int(input("请输入出生的年: ")) 9 m = int(input("请输入出生的月: ")) 10 d = int(input("请输入出生的日: ")) 11 12 t = (y, m, d, 0, 0, 0, 0, 0, 0) 13 # 先得到出生时,计算机计时秒数, 得到当前时间秒数 14 birth_time_sec = time.mktime(t) 15 life_sec = time.time() - birth_time_sec # 活了多少秒 16 life_days = life_sec / 60/ 60 // 24 17 print("您已出生", life_days, '天') 18 19 birth_tuple = time.localtime(birth_time_sec) 20 21 weeks = { 22 0: '星期一', 23 1: '星期二', 24 2: '星期三', 25 3: '星期四', 26 4: '星期五', 27 5: '星期六', 28 6: '星期日' 29 } 30 print("您出生那天是:", weeks[birth_tuple[6]]) 31 # print(birth_tuple[6]) # 星期几?
系统模块 sys
文档参见:
python_base_docs_html/系统模块sys.html
系统模块 sys
与系统相关的信息
sys模块的变量
变量
描述
sys.path
模块搜索路径 path[0] 是当前脚本程序的路径名,否则为 ''
sys.modules
已加载模块的字典
sys.version
版本信息字符串
sys.version_info
版本信息的命名元组
sys.platform
操作系统平台名称信息
sys.argv
命令行参数 argv[0] 代表当前脚本程序路径名
sys.copyright
获得Python版权相关的信息
sys.builtin_module_names
获得Python内建模块的名称(字符串元组)
标准输入输出时会用到
sys.stdin
标准输入文件对象,多用于input()
sys.stdout
标准输出文件对象,多用于print()
sys.stderr
标准错误输出文件对象, 用于输出错误信息
sys模块的方法
函数名
描述
sys.exit([arg])
退出程序,正常退出时sys.exit(0)
sys.getrecursionlimit()
sys.getrecursionlimit()
得到递归嵌套层次限制(栈的深度)
sys.setrecursionlimit(n)
得到和修改递归嵌套层次限制(栈的深度)
练习:
1. 编写函数fun, 其功能是计算并返回下列多项式的和
Sn = 1 + 1/1! + 1/2! + 1/3! + ... + 1/n!
(建议用数学模块中的math.factorial(x) 函数)
求当n = 20时,Sn的值
1 # 1. 编写函数fun, 其功能是计算并返回下列多项式的和 2 # Sn = 1 + 1/1! + 1/2! + 1/3! + ... + 1/n! 3 # (建议用数学模块中的math.factorial(x) 函数) 4 # 求当n = 20时,Sn的值 5 6 # 方法1 7 # def fun(n): 8 # from math import factorial as fac 9 # sn = 0 10 # for x in range(0, n + 1): 11 # sn += 1 / fac(x) 12 # return sn 13 14 # 方法2 15 # def fun(n): 16 # from math import factorial as fac 17 # return sum([1/fac(x) for x in range(n + 1)]) 18 19 # 方法3 20 def fun(n): 21 from math import factorial as fac 22 return sum(map(lambda x: 1/fac(x), range(n+1))) 23 24 print(fun(20)) # 2.718281828 25 26 27 28
2. 写一个程序,以电子时钟格式打印时间:
格式为:
HH:MM:SS
1 # 2. 写一个程序,以电子时钟格式打印时间: 2 # 格式为: 3 # HH:MM:SS 4 5 6 def show_time(): 7 import time 8 while True: 9 t = time.localtime() 10 print("%02d:%02d:%02d" % (t[3], t[4], t[5]), 11 end=' ') 12 time.sleep(0.1) 13 14 15 show_time()
1 # 2. 写一个程序,以电子时钟格式打印时间: 2 # 格式为: 3 # HH:MM:SS 4 5 6 def show_time(): 7 import time 8 while True: 9 t = time.localtime() 10 # print("%02d:%02d:%02d" % (t[3], t[4], t[5]), 11 # end=' ') 12 print("%02d:%02d:%02d" % t[3:6], end=' ') 13 14 time.sleep(0.1) 15 16 17 show_time()
3. 编写一个闹钟程序,启动时设置定时时间,到时间后打印
一句"时间到!" 然后程序退出
1 # 3. 编写一个闹钟程序,启动时设置定时时间,到时间后打印 2 # 一句"时间到!" 然后程序退出 3 4 5 6 def alarm(hour, minute): 7 import time 8 while True: 9 t = time.localtime() # 获取当前时间 10 print("%02d:%02d:%02d" % t[3:6], end=' ') 11 time.sleep(0.1) 12 # if t[3] == hour and t[4] == minute: 13 if t[3:5] == (hour, minute): 14 print("时间到!!!") 15 return 16 17 18 h = int(input("请输入小时: ")) 19 m = int(input("请输入分钟: ")) 20 alarm(h, m) 21 22 23 24 25 26 27 28