目录
装饰器decorators(专业提高篇)
问题:
函数名是变量,它绑定一个函数
函数名 /函数名()区别
什么是装饰器
装饰器是一个函数,主要作用是用来包装另一个函数或类(后面会讲)
作用:
是在不改变原函数名(或类名)的情况下改变被包装对象的行为
函数装饰器:
函数装饰器是指装饰器是一个函数,传入的是一个函数,返回的也是一个函数
语法:
def 装饰器函数名(参数):
语句块
return 函数对象
@装饰器函数名<换行>
def 函数名(形参列表):
语句块
#mydeco1.py
def mydeco(fn):
def fx():
print("fx函数被调用")
return fx
# myfunc加了mydeco装饰器,等同于在myfunc创建之后调用
# myfunc = mydeco(myfunc)
@mydeco
def myfunc():
print("函数myfunc被调用")
# 这样的写法可以用装饰器来代替
# 等同于
# @mydeco
# def myfunc()....
# myfunc = mydeco(myfunc)
# mydeco2.py
def mydeco(fn):
def fx():
print("++++++++这是myfunc调用之前++++++++")
# 要想在此处调用被装饰的函数myfunc怎么办?
fn() # 调用被装饰函数
print("--------这是myfunc调用之后--------")
return fx
@mydeco
def myfunc():
print("函数myfunc被调用")
# 此示例示意装饰器在不改变原函数和调用者行为的情
# 况下来改变原有函数功能
# 小赵写了一个装饰器函数:
def privillage_check(fn):
def fx(name, x):
print("正在检查权限.....")
fn(name, x) #权限通过可以调用相应函数
return fx
# 写一个操作数据的函数(此函数用来示意存钱操作)
@privillage_check
def savemoney(name, x): # 魏老师写的函数,用于存钱
print(name, '存钱', x, '元')
@privillage_check
def withdraw(name, x): # 冯老师写的函数,用于取钱
print(name, '取钱', x, '元')
# ---- 以下是调用者小闵写的程序 -------
savemoney("小张", 200)
savemoney('小赵', 400)
withdraw('小李', 500)
# mydeco4.py
# 此示例示意再加一个装饰器用来添加余额变动提醒功能
# 小姜写了一个装饰器函数用来发送短信
def send_message(fn):
def fy(name, x):
fn(name, x) # 先办业务
print("发短信给",name, '办理了', x, '元')
return fy
# 小赵写了一个装饰器函数:
def privillage_check(fn):
def fx(name, x):
print("正在检查权限.....")
fn(name, x) #权限通过可以调用相应函数
return fx
# 写一个操作数据的函数(此函数用来示意存钱操作)
@send_message
@privillage_check
def savemoney(name, x): # 魏老师写的函数,用于存钱
print(name, '存钱', x, '元')
@privillage_check
def withdraw(name, x): # 冯老师写的函数,用于取钱
print(name, '取钱', x, '元')
# ---- 以下是调用者小闵写的程序 -------
savemoney("小张", 200)
savemoney('小赵', 400)
withdraw('小李', 500)
看懂下面代码的调用关系及打印结果
def mydeco(fn):
print('装饰器函数被调用了....')
def fx():
print('fx被调用')
return fx()
@mydeco
def myfunc():
print('函数myfunc被调用')
myfunc()
myfunc()
myfunc()
函数的文档字符串
函数内第一次末赋值给任何变量的字符串是此函数的文档字符串
语法:
def 函数名(形参列表):
'''函数的文档字符串'''
函数语句块
示例:
def hello():
'''此函数用来打招呼...
这是函数的文档字符串'''
pass
>>> help(hello)
说明:
1.文档字符串通常用来说明本函数的功能和使用方法
2.在交互模式下,输入:help(函数名)可以查看函数的文档字符串
函数的__doc__属性
__doc__属性用于记录文档字符串
函数的__name__属性
__name__用于记录函数的名称
函数的定义语法:
@装饰器1
@装饰器2
...
def 函数名(位置形参, *元组形参(或*),命名关键字形参,**字典形参):
'''文档字符串'''
语句块
L = [1,2,3]
def f(n=0,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) #打印结果是什么?为什么? [100,200]
模块Module
什么是模块
模块是一个包含有一系列数据,函数,类等组成的程序组
模块是一个文件,模块文件名通常以'.py'结尾
作用:
1.让一些相关的数据,函数,类等有逻辑的组织在一起,是逻辑结构更加清晰
2.模块中的变量,函数和类等可提供给其他模块或程序使用
模块的分类:
1.内置模块(builtins)在解析器的内部可以直接使用
2.标准库模块,安装python时已安装具可直接使用
3.第三方模块(通常为开源),需要自己安装
4.用户自己编定的模块(可以作为其他人的第三方模块)
模块的导入import
import 语句
语法:
import 模块名1 [as 模块新名1],模块名2[as 模块新名2],...
示例:
import math #导入数学模块
import sys, os #导入sys和os模块
import copy as cp
作用:
讲一个模块整体导入到当前模块中
属性用法:
模块名.属性名
help(obj) 可以查看模块的文档字符串
练习:
1.输入一个圆的半径,打印出这个圆的面积
2.输入一个圆的面积,打印出这个圆的半径
#1.
import math
r = float(input("请输入圆的半径:"))
s = math.pi * r ** 2
print(s)
#2.
import math
area = float(input("请输入圆的面积:"))
r = math.sqrt(area/math.pi)
print(r)
from import 语句
语法:
from 模块名import 模块属性名[as 属性名新名1]
模块属性名2[as 属性名新名2]
作用:
将某模块的一个或多个属性导入到当前模块的作用域
示例:
from math import pi
from math import sin
from math import factorial as fac
dir 函数
dir([对象])返回一个字符串列表
作用:
1.如果没有参数调用,则返回当前作用域内所有变量的列表
2.如果给定一个对象作为参数,则返回这个对象的所在变量(属性)列表
1)对于一个模块,返回这个模块的全部变量
2)对于一个类对象,返回类对象的所有变量,并递归基类对象的所有变量
3)对于其他对象,返回所有变量,类变量和基类变量
数学模块math
时间模块time
练习:
写一个程序,输入您的出生日期
1) 算出你已经出生多少天?
2)算出你出生那天是星期几?
import time
# 1) 算出你已经出生多少天?
year = int(input("请输入年: "))
month = int(input("请输入月: "))
day = int(input("请输入日: "))
# 得到出生时距离1970年的秒数
birth_second = time.mktime((year,
month,
day,
0,
0,
0,
0,
0,
0))
cur_second = time.time() # 得到当前距离1970年的秒数
# 得到当前已生出多少秒
life_second = cur_second - birth_second
print("您已出生%d天" % (life_second / 60 / 60 // 24))
# 算出你出生的那天是星期几
birth_tuple = time.localtime(birth_second)
week = {0: "星期一",
1: "星期二",
2: "星期三",
3: "星期四",
4: "星期五",
5: "星期六",
6: "星期日"}
print("您的出生的期星的代号是:", week[birth_tuple[6]])