2018.7.17
day11回顾
高阶函数
map filter sorted
递归 recursion
闭包 closure
day12
装饰器 decorators(专业提高篇)
装饰器是一个函数,主要是作用是用来包装另一个函数或类(后面再讲)
装饰的目的是在不改变原函数名(或类名)的情况下,改变被包装对象的行为
函数装饰器
函数装饰器指装饰器传入的是一个函数,返回的也是一个函数
语法:
- def 装饰函数名(参数):
- 语句块
- return 函数对象
- @装饰器函数名<换行>
- def 函数名(形参列表):
- 语句块
示例:
#此示例示意函数装饰器定义用调用
def mydeco(fn):
def fx():
print('====================')
print('--------------')
return fx
@mydeco
def myfunc():
print('myfunc被调用')
myfunc()
myfunc()
myfunc()
#====================
#--------------
#====================
#--------------
#====================
#--------------
def mydeco(fn):
def fx():
fn()
print('====================')
print('--------------')
return fx
@mydeco
def myfunc():
print('myfunc被调用')
myfunc()
myfunc()
myfunc()
#myfunc被调用
#====================
#--------------
#myfunc被调用
#====================
#--------------
#myfunc被调用
#====================
#--------------
示例:
此示例示意一个函数两个装饰器先后顺序装饰
def privileged_chieck(fn):
def fx(name,x):
print('正在检查权限')
fn(name,x)
return fx
@privileged_chieck
def save_money(name,x): #存钱
print(name,'存钱',x,'元')
@privileged_chieck
def withdraw(name,x):
print(name,'取钱',x,'元')
save_money('小张',200)
save_money('小赵',200)
withdraw('小杨',200)
#正在检查权限
#小张 存钱 200 元
#正在检查权限
#小赵 存钱 200 元
#正在检查权限
#小杨 取钱 200 元
函数的文档字符串
函数内第一次来被赋值给任何变量的字符串是此函数的文档字符串
语法:
def 函数名(参数列表):
'函数文档字符串'
函数语句块
示例:
def myfun(name,x):
'''这是函数的文档字符串
name 表示人名
x表示钱数
'''
pass
>>>help(myfun)
说明:
1. 文档字符串通常用来说明本函数的功能和使用方法
2. 在交互模式下输入:help(函数名), 可以查看函数的‘文档字符串’
3.函数的文档字符串绑定在函数的_doc_属性上
函数的_doc_属性
用于绑定函数的文档字符串
函数定义语句(def 语句)的完整语法:
[@装饰器1]
[@装饰器2]
[...]
def 函数名([位置形参,],[*元组形参],[命名关键字形参],[**字典形参]):
'''文档字符串'''
语句块
注:[]可以省略内容
模块module
什么是模块:
模块是一个包含有一系列数据,函数,类等组成的程序组
模块是一个文件,模块文件名通常以.py结尾.
作用:
让一些相关的数据,函数,类等有逻辑的组织在一起,使逻辑结构更加清晰
模块中的数据,函数,类等可提供给其它模块或程序使用
模块的分类:
内建模块(builtins)在解析器的内可以直接使用
标准库模块,安装python时已安装且可以直接使用
第三方模块(通常开源),需要自己安装
用户自己编写的模块(可以作为其它人的第三方模块)
模块的导入语句
import 语句
语法:
import 模块1 [as 模块新名1],模块名2[as模块新名2],...
示例:
import math #导入math模块
import sys,os
作用:
将某模块整体导入到当前模块中
用法:
模块名.属性名 或 模块名.函数属性名(实参传参)
如:
math.factorial(5)
dir(obj) 函数返回所有属性的字符串列表
help(obj) 函数可以查看模块的相关文档字符串
练习:
1.输入一个圆的半径,打印出这个圆的面积
2.输入一个圆的面积,打印出这个圆的半径
(要求用math模块内的函数和数据实现)
import math
r = float(input("请输入圆的半径: "))
area = math.pi * r ** 2
print("面积是: ", area)
#方法一
# 输入一个圆的面积,打印出这个圆的半径
import math
area = float(input("请输入圆的面积: "))
t = area / math.pi
r = math.sqrt(t)
print('半径是:', r)
#方法二
# 输入一个圆的面积,打印出这个圆的半径
import math as m # m为math的新名字
area = float(input("请输入圆的面积: "))
t = area / m.pi
r = m.sqrt(t)
print('半径是:', r)
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)) # 120
from import * 语句
语法:
from 模块名 import *
作用:
将某模块的所有的属性导入到当前模块
示例:
- from math import *
- print(sin(pi/2))
- print(factorial(5))
dir 函数:
dir([对象])返回一个字符串的列表
说明:
如果没有给参数调用,则返回当前作用域内的所有变量的列表
如果给定一个对象为作参数,则返回这个对象的所有变量的列表
1)对于一个模块,返回这个模块的全部属性
2)对于一个类,返回这个类的所有变量,并递归基类对象的所有变量
3)对于其它的对象,返回所有类变量和基类变量
内建模块
math模块
模块名 math
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的反正切(返回值为为弧度) |
时间模块 time
import time
# 或
from time import xxx
# 或
from time import *
变量 | 描述 |
time.altzone | 夏令时时间与UTC时间差(秒为单位) |
time.daylight | 夏令时校正时间 |
time.timezone | 本地区时间与UTC时间差(秒为单位) |
time.tzname | 时区名字的元组, 第一个名字为未经夏令时修正的时区名, 第一个名字为经夏令时修正后的时区名 |
函数名 | 描述 |
time.time() | 返回从计算机元年至当前时间的秒数的浮点数(UTC时间为准) |
time.sleep(secs) | 让程序按给定秒数的浮点数睡眠一段时间 |
time.gmtime([secs]) | 用给定秒数转换为用UTC表达的时间元组 (缺省返回当前时间元组) |
time.asctime([tuple]) | 将时间元组转换为日期时间字符串 |
time.mktime(tuple) | 将本地日期时间元组转换为新纪元秒数时间(UTC为准) |
time.localtime([secs]) | 将UTC秒数时间转换为日期元组(以本地时间为准) |
练习:
写一个程序,输入你的出生日期,
1)算出你已经出生了多少天
2)算出你出生的那天是星期几
import time
year=int(input('请输入年 '))
month=int(input('请输入月 '))
day=int(input('请输入日 '))
tuple_birth=(year,month,day,0,0,0,0,0,0) #必须是9个,不足用0补齐
birth_second=time.mktime(tuple_birth)#出生计算机内部秒数
second=time.time()-birth_second#一共活了多少秒
print('你已经出生',second/60/60//24,'天')
# 算出生日那天是星期几
t = time.localtime(birth_second)
# print(t)
weeks = {
0: "星期一",
1: "星期二",
2: "星期三",
3: "星期四",
4: "星期五",
5: "星期六",
6: "星期日"
}
print("您出生的那天是:", weeks[t[6]])
系统模块 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模块的函数
函数名 | 描述 |
sys.exit([arg]) | 退出程序,正常退出时sys.exit(0) |
sys.getrecursionlimit() | 得到递归嵌套层次限制(栈的深度) |
sys.setrecursionlimit(n) | 得到和修改递归嵌套层次限制(栈的深度) |
练习:
1,请编写函数fun,其功能是计算下列多项式的和:
fn =1+1/1!+1/2!+1/3!+1/4!+....+1/n!
(建议用数学模块的factorial实现)
求当n等于100时,fn的值
看一下fn(100)的值是什么
import math
# 用循环实现
# def fun(n):
# s = 0
# for i in range(0, n + 1):
# s += 1 / math.factorial(i) # 1/i!
# return s
# 用递归实现
def fun(n):
if n == 0:
return 1
return 1 / math.factorial(n) + fun(n - 1)
print(fun(100)) # 2.71828
2,写一个程序,以电子时钟格式:
HH:MM:SS格式显示时间
要求每隔一秒变化一次
import time
def run():
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)
run()
3,写函数f(n)求下多项式的和
fn=1/1-1/3+1/5-1/7+1/9....1/(2*n-1)的和
求当n值为1000000时,
1)打印f(1000000)的值
2)打印f(1000000)*4的值,看看是什么
def f(n):
s = 0
sign = 1 # 符号(正负号)
for i in range(1, n + 1):
s += sign * 1 / (2 * i - 1)
sign *= -1
return s
# 1) 打印 f(1000000) 的值
print(f(1000000))
# 2) 打印 f(1000000) * 4的值,看看是什么
print(f(1000000) * 4)