python3基础12

day12

装饰器 decorator(专业提高篇)

什么是装饰器:
  装饰器是一个函数,主要作用是用来包装一个函数或类
  包装的目的是在不改变原函数(或类名)的情况下改变被包装对象的行为
  (不改变原有函数的基础上改变其功能)
函数装饰器
  是指装饰器是一个函数,传入的是一个函数,返回的是一个函数

  语法:
   def 装饰器函数(参数):
       语句块
       return 函数对象

   @装饰器函数名<换行>
   def 函数名(形参列表):
       语句块

函数装饰器原理:
  被装饰函数的变量(函数名)绑定装饰器函数调用后的返回的函数


示例见:
#mydecol.py代码

def mydeco(fn):   #------->装饰器函数
    def fx():
        print("fx被调用")
    return fx

@mydeco
def myfun():
    print("myfun被调用")


myfun()   #调用myfun
myfun()
myfun()

#mydecol2.py代码

def mydeco(fn):   #------->装饰器函数
    def fx():
        print("---这是被装饰函数调用之前---")
        fn()
        print("+++这是被装饰函数调用之后+++")
    return fx

@mydeco
def myfun():
    print("myfun被调用")

#上述@mydeco的原理是在def myfun语句调用之后加了如下语句
#myfun = mydeco(myfun)


myfun()   #调用myfun
myfun()
myfun()

# mydecol3.py代码
#此示例示意装饰器的应用场合及功能
#-----------以下是小李写的装饰器----------

def privileged_check(fn):
    print("zzzzzzzzzzzzzzzzzzzzzzz")#无savemoney调用多少次,这个只打印一次
    def fx(name,x):
        print("正在进行权限验证...")
        if True:
            fn(name,x)
        else:
            print("权限验证失败")
    return fx

#-----------以下是魏老师写的程序----------

@privileged_check
def savemoney(name,x):    #存钱业务
    print(name,'存钱',x,'元')

@privileged_check
def withdraw(name,x):
    print(name,'取钱',x,'元')

# -----------以下是调用者写的程序----------

savemoney('小张',200)
savemoney('小赵',400)

withdraw('小李',500)


# mydecol4.py

#此示例示意装饰器的应用场合及功能


#-----------以下是小李写的装饰器----------

def privileged_check(fn):
    print("zzzzzzzzzzzzzzzzzzzzzzz")
    #无savemoney调用多少次,这个只打印一次
    def fx(name, x):
        print("正在进行权限验证...")
        if True:
            fn(name, x)
        else:
            print("权限验证失败")
    return fx

def message_send(fn):
    def fy(n,money):
        fn(n,money)   #调用被装饰函数
        print("正在发送短信给", n, '...')
    return fy


#-----------以下是魏老师写的程序----------
@message_send
@privileged_check
def savemoney(name, x):    #存钱业务
    print(name, '存钱', x, '元')

#实质:
#savemoney = privileged_check(savemoney)
#savemoney = message_send(savemoney)

@privileged_check
def withdraw(name, x):
    print(name,'取钱', x, '元')

# -----------以下是调用者写的程序----------

savemoney('小张', 200)
savemoney('小赵', 400)


# withdraw('小李', 500)


函数的文档字符串:
  函数内第一次为赋值给任何变量的字符串是此函数的文档字符串
 
 语法:
   def 函数名(参数列表):
       '函数文档字符串'
       语句块

 说明:
 1.文档字符串通常用来说明函数的功能和使用方法
 2.在交互模式下,输入
 >>>help(函数名)    可以查看函数的文档字符串
 3.函数的文档字符串绑定在函数的_doc_属性上

示例:
  def mysum(n):
      '''mysum 函数用来求
       1+2+3+....+n的和
      '''
      retrun 100
  >>>help(mysum)


函数的_doc_属性
  _doc_属性是用于记录文档字符串(mysum._doc_)

注:  >>>mysum._   (查看mysum函数的全部属性)

函数的_name_属性
  _name_属性用与记录函数名

说明:
  以双下划线开头,以双下划线结尾的标识符通常代表pyhthon的特殊变量

函数定义的完整语法:
  [@装饰器1]
  [@装饰器2]
  [@装饰器3]
  ...
  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)  
f(100)
f(200)     #打印结果是什么?为什么?

#缺省参数[] 在def语句执行时床键此列表,并一直被f函数所绑定
#缺省参数不是调用的每一回都创建的,会保留之前的结果


模块  Module
 什么是模块
   模块是一个包含有一系列数据,函数,类等组成的程序组
   模块是一个文件,模块文件名通常以.py结尾

 作用:
   让一些相关的数据,函数,类等有逻辑的组织在一起,使逻辑结构更加清晰
   模块中的数据,函数,类等可以提供给其他模块或程序使用

 模块的分类:
 1.内置模块,再解释执行器内部定义,可以直接使用
 2.标准库模块,安装python时已安装且可以直接使用
 3.第三方模块(通常为开源),需要自己安装
 4.用户自定义模块(可以作为其他人的第三方模块)


模块的导入import

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)函数,可以查看模块的字符串文档

dir(math):
['__doc__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

练习一:
写程序:
1.输入一个圆的半径,打印这个圆的面积
2.输入一个圆的面积,打印出这个圆的半径
(要求用math模块内的函数和数据)

#方法一:
import math

r = float(input("请输入圆的半径:"))
print("圆的面积是:",math.pi*r**2)

s = float(input("请输入圆的面积:"))
print("圆的半径是:",math.sqrt(s / math.pi))

#方法二(别名)
import math as m   #给模块写别名


r = float(input("请输入圆的半径:"))
print("圆的面积是:",m.pi*r**2)

s = float(input("请输入圆的面积:"))
print("圆的半径是:",m.sqrt(s / m.pi))


from import 语句
 语法:
  from 模块名1 import 模块属性名1 [as 属性新名1],
  模块属性名2 [as 属性新名2],....

 作用:
  将某模块内的一个或多个属性导入到当前模块的作用域
 
 示例:
  from math import factorial as fac
   #只从math模块中导入了factorial重新命名为fac

  from math import sqrt,sin,cos
  #从math模块中导入了sqrt,sin,cos

  from math import pi    
  #只从math模块中导入了pi

  print("5的阶乘:",fac(5))
  print("9的平方根:",sqrt(9))
  print("圆周率是:",pi)


from import*语句  (不推荐使用,会造成变量覆盖)
  语法:
   from 模块名 import *
  作用:
   将某模块的所有属性导入到当前模块
  示例:
   from math import * 
   print(sin(pi / 2))
   print(factorial(5))  #可以直接使用math里的全部属性


>>> from math import *
>>> pi/2
1.5707963267948966
>>> from math import *
>>> pi
3.141592653589793

dir函数
 dir([对象])  返回一个字符串列表
 作用:
 1.如果没有参数调用,则返回当前作用域内所有变量的列表
 2.如果给定一个对象作为参数,则返回这个对象的所有变量的列表
  (1)对于一个模块,返回这个模块的全部属性
  (2)对于一个类对象,返回这个对象的所有变量并递归基类对象的所有变量
  (3)对于其他对象返回所有的变量,类变量和基类变量 


数学模块  math
  文档参见:
   数学模块math.HTML


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.html

注: CST为中国标准时间(China Standard Time UTC+8:00)

time.time() 
返回从计算机元年至当前时间的秒数的浮点数(UTC时间为准) 

time.sleep(secs) 
让程序按给定秒数的浮点数睡眠一段时间 

time.gmtime([secs]) 
用给定秒数转换为用UTC表达的时间元组
(缺省返回当前时间元组) 

time.asctime([tuple]) 
将时间元组转换为日期时间字符串 

time.mktime(tuple) 
如:time.mktime((2018, 8, 16, 16, 0, 0, 0))
将本地日期时间元组转换为新纪元秒数时间(UTC为准) 

time.localtime([secs]) 将UTC秒数时间转换为日期元组(以本地时间为准) 

练习二:
写一个程序,输入你的出生日期
1.算出你已经出生了多少天?
2.算出你出生那天是星期几?

import time
a = int(input("年"))
b = int(input("月"))
c = int(input("日"))
#出生的秒数(计算机元年开始)
brith_second = time.mktime((a, b, c, 0, 0, 0, 0, 0, 0)) 
#计算当前秒数(计算机元年开始)
cur_second = time.time()
lift_second = cur_second - brith_second
days = lift_second // 60 // 60 //24 
print("您共出生了%d天" % days  ) 
#得到出生那天的而时间元组
t = time.localtime(brith_second)
weeks = {0:'星期一',
         1:'星期二',
         2:'星期三',
         3:'星期四',
         4:'星期五',
         5:'星期六',
         6:'星期日'}
print("出生的那天是:",weeks[t[6]])


课后练习:
1.写一个程序,打印电子时间
格式为: HH:MM:SS  每过一秒钟刷新一次

#方法一:
import time

while True:
    time.sleep(1)
    s = time.time()
    s1 = time.gmtime(s + 8*60*60)
    print(s1[3], ':', s1[4], ':', s1[5])
#方法二:
import time
i = time.localtime()
s = time.mktime(i)
while True:
    s += 1
    d = time.localtime(s)
    print(d[3], ':', d[4], ':', d[5])
    time.sleep(1)


2.编写一个闹钟程序,启动时设置定时间,到时间打印一句:"时间到"
然后程序退出


#方法一:
import time

hour = int(input("请输入设定时间的小时:"))
minute = int(input("请输入设定时间的分钟:"))
second = int(input("请输入设定时间的秒钟:"))
while True:
    time.sleep(1)
    s = time.time()
    s1 = time.gmtime(s+8*60*60)
    if s1[3] == hour and s1[4] == minute and s1[5] == second:
        print("定时时间到")
        break

#方法二:
import time
i = time.mktime(time.localtime())
print(i)

h = int(input("请输入设定时间的小时:"))
m = int(input("请输入设定时间的分钟:"))
s= int(input("请输入设定时间的秒钟:"))
x = time.localtime()
t = (x[0],x[1],x[2],h,m,s,0,0,0)
n = time.mktime(t)
while True:
    time.sleep(1)
    i += 1
    if i == n:
        break
print('时间到')


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值