<1>什么是“闭包”?
如果在⼀个内部函数⾥,对在外部作⽤域(但不是在全局作⽤域)的变量进⾏引⽤,那么
内部函数就被认为是闭包(closure).
(即:闭包=函数块+引⽤环境)。
示例:
def outer(n):
num = n
def inner():
return num+1
return inner
print(outer(3)()) # 4
print(outer(5)()) # 6
输出结果:
4
6
<2>装饰器
下面的代码执行顺序是:首先因@cal_time,函数demo被当成参数传入到cal_time函数中,并开始执行函数内部代码语句,执行结束时会返回inner内部函数对象,但是不会自动调用inner函数;紧接着,用户输入demo()这时调用的不再是原来的demo函数了,而是inner内部函数,因为第一个步骤把demo函数当成参数传入cal_time函数中返回了inner,用户在有@cal_time的情况下输入demo等同于inner();所以,最后开始执行inner函数内部的代码语句,inner函数里头fn()相当于demo(),再一次调用了原来的demo函数。
import time #导入time模块
def cal_time(fn): #必要的装饰器语法
print("我是外部函数")
def inner(): #必要的修饰器语法
start=time.time()
fn()
end=time.time()
print("代码执行耗时为{}秒".format(end - start)) #打印代码执行耗费时间
return inner #必要的装饰器语法
@cal_time #必要的装饰器语法
def demo():
s=0
for i in range(1,19900000):
s*=i
print(s)
demo() #此时的demo()不再是指调用原来的demo函数了,而是调用了inner函数
输出结果:
我是外部函数
0
代码执行耗时为1.0775115489959717秒
<3>模块
⼀个py⽂件就是⼀个模块。
导入模块时,系统会把模块里所有的代码都运行一遍。
导入模块的五种方法:
import time #直接导入time模块
from random import randint #从random模块中导入方法或者变量
from math import * #从模块中导入所有的方法和变量,和上面的区别是,这种在使用的时候不需要写“模块名.方法”
import datetime as dt #导入模块并给模块取别名
from copy import deepcopy as dp #从模块中导入方法或者变量并重新起别名
自定义模块实际上就是自己写一个py文件,自定义模块一定要遵守命名规则才可以被导入使用。<由数字、字母和下划线组成,数字不能作为开头!>
import pandans 与 from pandans import * 的区别如下:
前者:使用模块的变量和方法时需要以“模块名.变量名(或方法名)”才可使用
后者:使用模块的变量和方法时直接写变量名(或方法名)即可;本质是读取模块里的__all__属性,只能使用__all__里面的变量和方法。
以一个下划线开始的变量,建议只在原来的模块中使用,别的模块不要使用。这些变量或者函数一般是原来模块的中间变量或者中间函数,强行调用有可能出错。
例如datatime模块中的_is_leap(year)是用于datatime模块中使用的。如果原来的模块里做了del 变量名或者函数名的话,即使模块被导入后,里面被del的都不能被调用。