一.作用域
在python中,作用域分为两种:全局作用域和局部作用域。
全局作用域是定义在文件级别的变量,函数名。而局部作用域,则是定义函数内部。
关于作用域,我们要理解两点:
a.在全局不能访问到局部定义的变量
b.在局部能够访问到全局定义的变量,但是不能修改全局定义的变量(当然有方法可以修改)
下面我们来看看下面实例:
x = 1
def funx():
x = 10
print(x) # 打印出10
funx()
print(x) # 打印出1
如果局部没有定义变量x,那么函数内部会从内往外开始查找x,如果没有找到,就会报错
x = 1
def funx():
print(x)
funx()
print(x) # 打印出1
x = 1
def funx():
def func1():
print(x)
func1()
funx()
print(x) # 打印出1
因此,关于作用域的问题,只需要记住两点就行:
全局变量能够被文件任何地方引用,但修改只能在全局进行操作;如果局部没有找到所需的变量,就会往外进行查找,没有找到就会报错。
二.高级函数
我们知道,函数名其实就是指向一段内存空间的地址,既然是地址,那么我们可以利用这种特性来。
def delete(ps):
import os
filename = ps[-1]
delelemetns = ps[1]
with open(filename, encoding='utf-8') as f_read,\
open('tmp.txt', 'w', encoding='utf-8') as f_write:
for line in iter(f_read.readline, ''):
if line != '\n': # 处理非空行
if delelemetns in line:
line = line.replace(delelemetns,'')
f_write.write(line)
os.remove(filename)
os.rename('tmp.txt',filename)
def add(ps):
filename = ps[-1]
addelemetns = ps[1]
with open(filename, 'a', encoding='utf-8') as fp:
fp.write("\n", addelemetns)
def modify(ps):
import os
filename = ps[-1]
modify_elemetns = ps[1]
with open(filename, encoding='utf-8') as f_read, \
open('tmp.txt', 'w', encoding='utf-8') as f_write:
for line in iter(f_read.readline, ''):
if line != '\n': # 处理非空行
if modify_elemetns in line:
line = line.replace(modify_elemetns, '')
f_write.write(line)
os.remove(filename)
os.rename('tmp.txt', filename)
def search(cmd):
filename = cmd[-1]
pattern = cmd[1]
with open(filename, 'r', encoding="utf-8") as f:
for line in f:
if pattern in line:
print(line, end="")
else:
print("没有找到")
dic_func ={'delete': delete, 'add': add, 'modify': modify, 'search': search}
while True:
inp = input("请输入您要进行的操作:").strip()
if not inp:
continue
cmd_1 = inp.split()
cmd = cmd_1[0]
if cmd in dic_func:
dic_func[cmd](cmd_1)
else:
print("Error")
将函数作为字典值,实现文本数据的增删查改操作
b.函数名可以作为返回值
def outer():
def inner():
pass
return inner
s = outer()
print(s)
######输出结果为#######
<function outer.<locals>.inner at 0x000000D22D8AB8C8>
c.函数名可以作为一个参数
def index():
print("index func")
def outer(index):
s = index
s()
outer(index)
######输出结果#########
index func
所以满足上面两个条件中的一个,都可以称为高级函数.
三.闭包函数
闭包函数必须满足两个条件:1.函数内部定义的函数 2.包含对外部作用域而非全局作用域的引用
下面通过一些实例来说明闭包函数:
实例一:以下仅仅在函数内部定义了一个函数,但并非闭包函数.
def outer():
def inner():
print("inner func excuted")
inner() # 调用执行inner()函数
print("outer func excuted")
outer() # 调用执行outer函数
####输出结果为##########
inner func excuted
outer func excuted
实例二:以下在函数内部定义了一个函数,而且还引用了一个外部变量x,那么这个是闭包函数么?答案:不是
x = 1
def outer():
def inner():
print("x=%s" %x) # 引用了一个非inner函数内部的变量
print("inner func excuted")
inner() # 执行inner函数
print("outer func excuted")
outer()
#####输出结果########
x=1
inner func excuted
outer func excuted
在回头来看看对闭包函数的定义,是不是两条都满足?聪明的你,一定发现不满足第二条.对,这里的变量x,是属于全局变量,而非外部作用于域的变量。再来看看下面例子:
def outer():
x = 1
def inner():
print("x=%s" %x)
print("inner func excuted")
inner()
print("outer func存地址,再将其赋值给home,这里的home不在是原来的的那个函数,而是被装饰以后的函数了。
像home = timmer(home)这样的写法,python给我们提供了一个便捷的方式------语法糖@.
以后我们再要在被装饰的函数之前写上@timmer,它的效果就和home = timmer(home)是一样的。
如果一个函数被多个装饰器装饰,那么执行顺序是怎样的。
import time
import random
def timmer(func):
def wrapper():
start_time = time.time()
func()
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return wrapper
def auth(func):
def deco():
name=input('name: ')
password=input('password: ')
if name == 'egon' and password == '123':
print('login successful')
func() #wrapper()
else:
print('login err')
return deco
@auth # index = auth(timmer(index))
@timmer # index = timmer(index)
def index():
time.sleep(3)
print('welecome to index page')
index()
实验结果表明,多个装饰器装饰一个函数,其执行顺序是从下往上。
总结
以上所述是小编给大家介绍的python装饰器实例大详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对社区网站的支持! |