###day11 回顾
- 函数式编程
可重入函数:
输入一定.结果必然一定(在函数内部不访问除局部变量以外的
任何变量)
高阶函数:
1. 函数返回一个函数
2. 函数可以接收函数作为参数传入
三个内建的高阶函数
map, filter, sorted
示例:
求: 1 + 4 + 9 + 16 + … + 81
sum(map(lambda x:x**2, range(1, 10)))
求: 1 + 3 + 5 + 7 + 9 + … + 99
sum(filter(lambda x: x%2, range(100)))
sorted(可迭代对象, key=获取依据的函数,
reverse=False)
###递归函数 recursion function
闭包: closure
内嵌函数引用了外部嵌套函数的变量,这个内嵌函数就是闭包
闭包的特点:
闭包使用的外部嵌套函数的变量会延迟销毁
全局变量和局部变量
```
def make_power(y):
def fn(x):
return x ** y
return fn
pow2 = make_power(2)
print(pow2(5))
print(pow2(6))
pow3 = make_power(3)
pow4 = make_power(4)
pow100 = make_power(100)
```
新的一天
装饰器 decorators(专业提高篇)
装饰器是一个函数,主要作用是用来包装另一个函数或类(后面才讲)
作用:
在不修改被装饰函数的源代码,不改变被装饰函数的调用方式的情况
下添加或改变原函数的功能
语法:
def 装饰器函数名(fn):
语句块
return 函数对象
@装饰器函数名<换行>
def 被装饰函数名(形参列表):
语句块
示例见:
mydeco1.py
```python
# 此示例示意用装饰器来改变函数myfunc的功能
def mydeco(fn):
def fx():
print('+++++++++++')
fn()
print('-----------')
return fx
def myfunc():
print("myfunc被调用")
myfunc = mydeco(myfunc) # ????
myfunc()
myfunc()
myfunc()
```
mydeco2.py
```python
# 此示例示意用装饰器来改变函数myfunc的功能
def mydeco(fn):
def fx():
print('+++++++++++')
fn()
print('-----------')
return fx
@mydeco
def myfunc():
print("myfunc被调用")
# myfunc = mydeco(myfunc) #此行等同于在myfunc上加@mydeco
myfunc()
myfunc()
myfunc()
```
mydeco3.py
```python
# mydeco3.py
# 此示例示意用装饰器的语法来改变银行业务的需求
# 以下是小钱写的装饰器
def privileged_check(fn):
def fx(n, x):
print("正在验证权限...")
fn(n, x)
return fx
def send_message(fn):
def fy(n, x):
fn(n, x)
print("正在发短信息给", n, '...')
return fy
# -------- 以下是老师的写的程序--------
@privileged_check
def savemoney(name, x):
print(name, '存钱', x, '元')
@send_message
@privileged_check
def withdraw(name, x):
print(name, '取钱', x, '元')
# ---------以下是调用者小张写的程序--------
savemoney("小王", 200)
savemoney("小赵", 400)
withdraw("小李", 500)
```
函数的文档字符串
函数内第一次没有赋值给任何变量的字符串是此函数的文档字符串
语法:
def 函数名(参数列表):
'函数文档字符串'
语句块
示例:
def myfunc(x, y):
'''这是myfunc的文档字符串
参数x 代表xxx
参数y 代表yyy
'''
pass
说明:
文档字符串通常用来说明本函数的功能和使用方法
在交互环境下输入: help(函数名) 可以查看函数的文档字符串
函数的文档字符串绑定在函数的__doc__属性上
函数的__doc__ 属性
__doc__属性用于绑定函数的文档字符串
如:
print(myfunc.__doc__)
函数定义语句(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) # [200]
解决方法 :
def f(n=0, lst=None):
if lst is None: # 说明没有传第二个实参
lst = [] # 创建一个空列表,然后再绑定
lst.append(n)
print(lst)
模块 Module
什么是模块
模块是一个包含有一系列数据,函数,类等组成的程序组
模块是一个文件,模块文件名通常以.py结尾
作用:
1. 让一些相关的数据,函数,类等有逻辑的组织在一起,使逻辑结
构更加清晰
2. 模块中的数据,函数和类等可提供给其它函数或程序使用
模块的分类
1. 内置模块, 在解析器内部可以直接使用.
2. 标准库模块,安装python时已安装且可直接使用
3. 第三方模块(通常为开源), 需要自己安装
安装方法:
$ sudo pip3 install 模块名
$ sudo pip3 install tensorflow
4. 用户自己编写的模块(可以作为其它人的第三方模块)
###模块的导入
- import 语句
语法:
import 模块名1 [as 模块新名1], 模块名2 [as 模块新名2],…
作用:
将某模块整体导入到当前模块中
用法:
模块名.属性名
示例:
import math
import sys, time
print(math.factorial(5)) # 120
- 相关函数:
dir(obj) 返回模块所有属性的列表
help(obj) 查看模块相关的文档字符串
练习:
公式:
周长=2*pi*r(半径)
面积=pi * r ** 2
1. 输入一个圆的半径,打印出这个圆的面积
s = math.pi*math.pow(r,2)
2. 输入一个圆的面积,打印出这个圆的半径
r = math.sqrt(s/(math.pi))
(要求用math模块内的函数和数据)
- from import 语句
语法:
from 模块名 import 模块属性名1 [as 属性新名1], 模块属
性名2 [as 属性新名2], ...
作用:
将某模块内的一个或多个属性导入到当前模块的作用域
示例:
from math import factorial as fac
from math import sin
from math import pi
print(fac(5))
print(sin(pi/2))
- from import *语句
语法:
from 模块名 import *
作用:
将某模块的所有属性导入到当前模块
示例:
from math import *
sin(pi/2)
factorial(6)
dir 函数:
格式:
dir([对象]) 返回一个字符串列表
作用:
如果没有参数,则返回这个对象的所有变量的列表
如果给定一个对象作为参数,则返回这个对象的所有变量的列表
对于一个模块,返回这个模块的全部变量
对于一个类对象,返回类对象的所有变量,并递归基类对象的所
有变量
对于其它对象,返回所有变量,类变量和基类变量
内建模块的使用:
数学模块
模块名 math
文档参见:
数据 描述
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的反正切(返回值为为
时间模块
模块名: time
文档参见:
数据 描述
time.altzone 夏令时时间与UTC时间差(秒为单位)
time.daylight 夏令时校正时间
time.timezone 本地区时间与UTC时间差(秒为单位)
time.tzname 时区名字的元组, 第一个名字为未经夏令时修正的时区名,
第一个名字为经夏令时修正后的时区名
注: CST为中国标准时间(China Standard Time UTC+8:00)
函数名 描述
time.time() 返回从计算机元年至当前时间的秒数的浮点数(UTC时间为准)
time.gmtime([secs]) 用给定秒数转换为用UTC表达的时间元组
(缺省返回当前时间元组)
time.localtime([secs]) 将UTC秒数时间转换为日期元组(以本地时间为准)
time.mktime(tuple) 将本地日期时间元组转换为新纪元秒数时间(UTC为准)
time.asctime([tuple]) 将时间元组转换为日期时间字符串
time.sleep(secs) 让程序按给定秒数的浮点数睡眠一段时间
示例:
t = (2008, 8, 8, 20, 8, 8, 0, 0, 0)
time.mktime(t) # 1218197288.0
示例见:
```
import time
print("这是第一个打印")
time.sleep(10) # 让程序停下来,睡眼10秒后再继续
print("这是第二个打印")
```
练习:
写一个程序,输入你的出生年月日,
1) 算出你已经出生多少天?
2) 算出你出生那天是星期几?
```
import time
year = input("出身年份:")
month = input("出生月份:")
day = input("出生日:")
time_tup = (int(year),int(month),int(day),0,0,0,0,0,0)
birth_time = time.mktime(time_tup)
left_time = time.time()-birth_time
left_time = left_time/3600//24
print("天数:",left_time)
print(time.localtime(birth_time)[6]+1)
```
练习:
1. 写一个程序,以电子时钟的格式打印时间
格式为:
HH:MM:SS
```
import time
def show_time():
# 在此处显示时间
while True:
# 取出本地时间
t = time.localtime()
# 显示时间
# print("%02d:%02d:%02d" % (t[3], t[4], t[5]), end='\r')
print("%02d:%02d:%02d" % t[3:6], end='\r')
time.sleep(1)
show_time()```
2. 编写一个闹钟程序,启动时设定时间,到时间后打印一句语:
时间到,然后退出程序
```
def alarm(h, m):
'''h 代表小时
m 代表分钟
'''
import time
while True:
t = time.localtime()
print("%02d:%02d:%02d" % t[3:6], end='\r')
if h == t[3] and m == t[4]:
print("时间到!!!")
return
time.sleep(1)
hour = int(input("请输入小时: "))
minute = int(input("请输入分钟: "))
alarm(hour, minute)
```
3. 编写函数fun(n) 返回下列多项式的和
Sn = 1 + 1/1! + 1/2! + 1/3! + ... + 1/n!
求n 为10时,Sn的值
```
# 方法1
# def fun(n):
# import math
# sn = 0
# for x in range(n + 1):
# sn += 1 / math.factorial(x)
# return sn
# 方法2
def fun(n):
import math
# return sum([1/math.factorial(x) for x in range(n+1)])
return sum(map(lambda x: 1 / math.factorial(x),
range(n + 1)))
print(fun(10))
print(fun(20))
```