python基础(12)——装饰器 & def函数语法 & 模块的导入 & 时间模块
一、装饰器 decorator(专业提高篇)
什么是装饰器
装饰器是一个函数,主要作用是用来包装另一个函数或类(后面才讲)
包装的目的是在不改变原函数(或类名)的情况下改变被包装对象 的行为
函数装饰器
是指装饰器是一个函数,传入的是一个函数,返回的是一个函数
语法:
def 装饰器函数名(参数):
语句块
return 函数对象
@装饰器函数名<换行>
def 函数名(形参列表):
语句块
原理:
被装饰函数的变量(函数名)绑定装饰器函数调用后的返回的函数
(即用装饰器函数的返回值改变原函数名变量的绑定关系)
1 # 此示例示意装饰器函数的定义和调用及装饰原理 2 def mydeco(fn): # <<<---- 装饰器函数 3 def fx(): 4 print("fx被调用") 5 return fx 6 7 # @mydeco 8 def myfun(): 9 print("myfun被调用") 10 11 # 上述 mydeco的原理是在 def myfun语句调用之后加了如下语句 12 myfun = mydeco(myfun) 13 14 myfun() # 调用myfun 15 myfun() 16 myfun()
1 # 此示例示意装饰器函数用来包装被装饰函数 2 def mydeco(fn): # <<<---- 装饰器函数 3 def fx(): 4 print("----这是被装饰函数调用之前----") 5 fn() # 调用被装饰函数 6 print("++++这是被装饰函数调用之后++++") 7 return fx 8 9 @mydeco 10 def myfun(): 11 print("myfun被调用") 12 13 14 myfun() # 调用myfun 15 # myfun() 16 # myfun()
1 #3. 此示例示意装饰器的应用场合及功能 2 # ------ 以下是小李写的一个装饰器函数---------------- 3 def privileged_check(fn): 4 def fx(name, x): 5 print("正在进行权限验证.....") 6 if True: 7 fn(name, x) 8 else: 9 print("权限验证失败") 10 return fx 11 #--------------发送短信-------------------------- 12 def message_send(fn): 13 def fy(n, money): 14 fn(n, money) #调用被装饰函数 15 print("正在发送短信给",n ,"...") 16 return fy 17 # ------ 以下是小魏写的程序---------------------- 18 @message_send 19 @privileged_check- 20 def savemoney(name, x): # 存钱业务 21 print(name, '存钱', x, '元') 22 # #实质: 23 # #savemoney = privileged_check(savemoney) 24 # #savemoney = message_send(savemoney) 25 26 @privileged_check 27 def withdraw(name, x): 28 print(name, '取钱', x, '元') 29 # --------以下是调用者小张写的程序------------------ 30 savemoney('小王', 200) 31 savemoney('小赵', 400) 32 withdraw('小李', 500) 33 #------------------------------------------------
1 # 此示例示意装饰器的应用场合及功能 2 # ------ 以下是小李写的一个装饰器函数--------- 3 def privileged_check(fn): 4 def fx(name, x): 5 print("正在进行权限验证.....") 6 if True: 7 fn(name, x) 8 else: 9 print("权限验证失败") 10 return fx 11 ---------------------------------------- 12 def message_send(fn): 13 def fy(n, money): 14 fn(n, money) # 调用被装饰函数 15 print("正在发送短信给", n, '...') 16 return fy 17 # ------ 以下是小魏写的程序------- 18 @message_send 19 @privileged_check 20 def savemoney(name, x): # 存钱业务 21 print(name, '存钱', x, '元') 22 # 实质: 23 # savemoney = privileged_check(savemoney) 24 # savemoney = message_send(savemoney) 25 26 @privileged_check 27 def withdraw(name, x): 28 print(name, '取钱', x, '元') 29 # --------以下是调用者小张写的程序--------------- 30 savemoney('小王', 200) 31 # savemoney('小赵', 400) 32 # withdraw('小李', 500)
二、函数的文档字符串:
函数内第一次未赋值给任何变量的字符串是此函数的文档字符串
语法:
def 函数名(参数列表):
'函数文档字符串'
语句块
说明:
1. 文档字符串通常用来说明函数的功能和使用方法
2. 在交互模式下,输入:
>>> help(函数名) 可以查看函数的文档字符串
3. 函数的文档字符串绑定在函数的__doc__属性上
示例:
def mysum(n):
'''mysum 函数用来求
1 + 2 + 3 + .... + n 的和
'''
return 100
>>> help(mysum)
1、函数的 __doc__ 属性
__doc__ 属性用于记录文档字符串
2、函数的 __name__ 属性
__name__属性用于记录函数名
3、说明:
以双下划线开头,以双下划线结尾的标识符通常代表python的特殊变量
4、函数定义的完整语法:
[@装饰器名1]
[@装饰器名2]
[...]
def 函数名(位置形参, *元组形参名, 命名关键字形参, **字典形参):
'文档字符串'
语句块
面试题:
L = [1, 2, 3]
# 缺省参数[] 在def语句执行时创建此列表,并一直被f函数所绑定
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] 打印结果是什么,为什么?
1 L = [1, 2, 3] 2 def f(n=0, lst=[]): #在def语句执行时创建次列表,并一直被f函数所绑定 3 lst.append(n) 4 print(lst) 5 6 f(4, L) #[1, 2, 3, 4] 7 f(5, L) #[1, 2, 3, 4, 5] 8 f(100) #[100] 9 f(200) #[100, 200] 打印的结果是什么?为什么? 10 # 答:在def语句执行时创建次列表,并一直被f函数所绑定
三、模块 Module
什么是模块
模块是一个包含有一系列数据,函数,类等组成的程序组
模块是一个文件 ,模块文件名通常以.py结尾
作用:
让一些相关的数据,函数,类等有逻辑的组织在一起,使逻辑结构更新加清晰
模块中的数据,函数和类等可以提供给其它模块或程序使用
模块的分类:
1. 内置模块, 在解释执行器内部定义,可以直接使用
2. 标准库模块, 安装python时已安装且可以直接使用
3. 第三方模块(通常为开源), 需要自己安装
4. 用户自定义模块(可以作为其它人的第三方模块)
四、模块的导入 import
1、import 语句
语法:
import 模块名1 [as 模块新名1], 模块名2 [as 模块新名2], ...
作用:
将某模块整体导入到当前模块中
示例:
import math # 导入数学模块
import sys, time # 导入系统模块和时间模块
见: import1.py
用法:
模块名.属性名
如:
print(math.factorial(5))
print(math.cos(0))
函数:
dir(obj) 函数,返回所有属性的字符串列表
help(obj)函数,可以查看模块的文档字符串
练习:
写程序:
1) 输入一个圆的半径,打印出这个圆的面积
2) 输入一个圆的面积,打印出这个圆的半径
(要求用math模块内的函数和数据)
1 import math 2 # 1) 输入一个圆的半径,打印出这个圆的面积 3 r = float(input("请输入圆的半径: ")) 4 area = math.pi * r ** 2 5 print("面积是:", area) 6 # 2) 输入一个圆的面积,打印出这个圆的半径 7 area = float(input("请输入圆的面积: ")) 8 r = math.sqrt(area / math.pi) 9 print("半径是:", r) 10 11 # #用as简化------------------------------ 12 import math as m 13 # 1) 输入一个圆的半径,打印出这个圆的面积 14 r = float(input("请输入圆的半径: ")) 15 area = m.pi * r ** 2 16 print("面积是:", area) 17 # 2) 输入一个圆的面积,打印出这个圆的半径 18 area = float(input("请输入圆的面积: ")) 19 r = m.sqrt(area / m.pi) 20 print("半径是:", r)
2、from import 语句
语法:
from 模块名 import 模块属性名1 [as 属性新名1], 模块属性名2 [as 属性新名2], .....
作用:
将某模块内的一个或多个属性导入到当前模块的作用域
示例:
from math import factorial as fac
from math import sqrt
from math import pi, e, sin, cos
print('5的阶乘是:', fac(5))
print('9的平方根是:', sqrt(9))
print('圆周率是:', pi)
3、from import * 语句
语法:
from 模块名 import *
作用:
将某模块的所有属性导入到当前模块
示例:
from math import *
print(sin(pi/2))
print(factorial(5)) # 可以直接使用math里的全部属性
4、dir 函数:
dir([对象]) 返回一个字符串列表
作用:
1.如果没有参数调用,则返回当前作用域内所有变量的列表
2.如果给定一个对象作为参数,则返回这个对象的所有变量的列表
1) 对于一个模块,返回这个模块的全部属性
2) 对于一个类对象,返回类对象的所有变量并递归基类对象的所有变量
3) 对于其它对象返回所有变量,类变量和基类变量
五、数学模块 math
- 模块名: math
- 注:
- linux下为内建模块
- Mac OS下为标准库模块
数学模块用法:
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
1 # 时间模块 2 print('程序开始') 3 import time 4 time.sleep(10) 5 print("程序结束")
- 此模块提供了时间相关的函数,且一直可用
时间简介
-
公元纪年是从公元 0000年1月1日0时开始的
-
计算机元年是从1970年1月1日0时开始的,此时时间为0,之后每过一秒时间+1
-
UTC 时间 (Coordinated Universal Time) 是从Greenwich时间开始计算的.
UTC 时间不会因时区问题而产生错误 -
DST 阳光节约时间(Daylight Saving Time),又称夏令时, 是一个经过日照时间修正后的时间
时间元组
- 时间元组是一个9个整型元素组成的,这九个元素自前至后依次为:
- 四位的年(如: 1993)
- 月 (1-12)
- 日 (1-31)
- 时 (0-23)
- 分 (0-59)
- 秒 (0-59)
- 星期几 (0-6, 周一是 0)
- 元旦开始日 (1-366)
- 夏令时修正时间 (-1, 0 or 1).
- 注:
- 如果年份值小于100,则会自动转换为加上1900后的值
模块名: time
时间模块用法:
import time # 或 from time import xxx # 或 from time import *
| 数据 | 描述 |
|---|---|
| time.altzone | 夏令时时间与UTC时间差(秒为单位) |
| time.daylight | 夏令时校正时间 |
| time.timezone | 本地区时间与UTC时间差(秒为单位) |
| time.tzname | 时区名字的元组, 第一个名字为未经夏令时修正的时区名, 第一个名字为经夏令时修正后的时区名 |
注: CST为中国标准时间(China Standard Time UTC+8:00)
| 函数名 | 描述 |
|---|---|
| time.time() | 返回从计算机元年至当前时间的秒数的浮点数(UTC时间为准) |
| time.sleep(secs) | 让程序按给定秒数的浮点数睡眠一段时间 |
| time.gmtime([secs]) | 用给定秒数转换为用UTC表达的时间元组 (缺省返回当前时间元组) |
| time.asctime([tuple]) | 将时间元组转换为日期时间字符串 |
| time.mktime(tuple) | 将本地日期时间元组转换为新纪元秒数时间(UTC为准) |
| time.localtime([secs]) | 将UTC秒数时间转换为日期元组(以本地时间为准) |
练习:
写一个程序,输入你的出生日期
1) 算出你已经出生了多少天?
2) 算出你出生那天是星期几?
1 import time 2 year = int(input("请输入出生的年: ")) 3 month = int(input("请输入出生的月: ")) 4 day = int(input("请输入出生的年日: ")) 5 # 出生的秒数(计算机元年开始) 6 birth_second = time.mktime((year, month, day, 0, 0, 0 ,0, 0, 0)) 7 cur_second = time.time() # 当前的秒数(计算机元年开始) 8 life_second = cur_second - birth_second 9 days = life_second // 60 // 60 // 24 # 天数 10 print("您共出生了%d天" % days) 11 # 得到出生那天的时间元组 12 t = time.localtime(birth_second) 13 week = { 14 0: "星期一", 15 1: "星期二", 16 2: "星期三", 17 3: "星期四", 18 4: "星期五", 19 5: "星期六", 20 6: "星期日" 21 } 22 print("出生那天是:", week[t[6]])
练习:
1. 写一个程序,打印电子时间:
格式为:
HH:MM:SS
每过一秒钟刷新一次
1 import time 2 3 while True: 4 t = time.localtime() # 得到当前时间的元组 5 # print("%02d:%02d:%02d" % (t[3], t[4], t[5])) 6 print("%02d:%02d:%02d" % t[3:6], end='\r') 7 time.sleep(1)
2. 编写一个闹钟程序,启动时设置定时间, 到时间后打印一句:
"时间到",然后程序退出
1 import time 2 3 def alarm(h, m): 4 while True: 5 # 得到当前时间 6 t = time.localtime() 7 print("%02d:%02d:%02d" % t[3:6], end='\r') 8 # if h == t[3] and m == t[4]: 9 if (h, m) == t[3:5]: 10 print("\n时间到") 11 break 12 time.sleep(1) 13 14 hour = int(input("请输入定时小时: ")) 15 minute = int(input("请输入定时分钟: ")) 16 alarm(hour, minute)
posted on 2018-10-12 17:32 破天荒的谎言、谈敷衍 阅读(493) 评论(0) 收藏 举报
浙公网安备 33010602011771号