0
点赞
收藏
分享

微信扫一扫

流暢的python---函數闭包

SDKB英文 2022-06-17 阅读 72

一、函数的定义及其应用
所谓函数,就是把具有独立功能的代码块组织成为一个小模块,在需要的时候调用
函数的使用包含两个步骤
1.定义函数–封装独立的功能
2.调用函数–享受封装的成果
函数的作用:在开发时,使用函数可以提高编写的效率以及代码的重用‘’
函数:函数是带名字的代码块,用于完成具体的工作 需要在程序中多次执行同一项任务时,你无需反复编写完成该任务的代码,而只需调用该任务的函数

最簡單函數:例子

def fib(n):
if n<=1:
return n
else:
return fib(n-1)+fib(n-2)


a=fib(10)
print (a)

for i in range(1, 20):
print(fib(i), end=' ')



打印结果:
55
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181

 

 

闭包函数:闭包的特点就是内部函数引用了外部函数中的变量

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat May 2 23:04:22 2020

@author: root

函数名.__closure__ 在函数是闭包函数时,返回一个cell元素;不是闭包时,返回None。

"""


def func():
name=100
def inner():
print (name)
print(inner.__closure__) # (<cell at 0x0000027C14EB85E8: str object at 0x0000027C14F54960>,)

return inner

f=func()
f()

结果:
100
(<cell at 0x7f568408d050: function object at 0x7f568405c560>, <cell at 0x7f567feb9310: int object at 0x55d3c129df60>)
def line_conf(a,b):
def line(x):
return a*x+b
return line

lineA=line_conf(2,1) #y=2x+1
lineB=line_conf(3, 4) #y=3x+1

print (lineA(1))
print (lineB(1))

__closure__属性返回的是一个元组对象,包含了闭包引用的外部变量。

 

 

 

案例: 1、若主函数内的闭包不引用外部变量,就不存在闭包,主函数的_closure__属性永远为None:

 

·  若主函数内的闭包不引用外部变量,就不存在闭包,主函数的_closure__属性永远为None

def line_conf():
a=1
b=2
def line(x):
print (x+1)

return line


l=line_conf()
print (l.__closure__) #None
try:
for i in l.__closure__: #报错
print (i.cell_contents)
except Exception as e:
print ('NoneType')

 

若主函数没有return 子函数,就不存在闭包

def line_conf():
a=1
b=2
def line(x):
print (x+1)

return a+b


l=line_conf()
print (l.__closure__) #抛异常

 

 

 

闭包下保存运行环境

_list=[]
for i in range(5):
def fun(a):
return i+a
_list.append(fun)
print(_list)
for f in _list:
print(f(1))

只保存最后一个:y=4+a
# [<function fun at 0x109690d08>, <function fun at 0x109690c80>, <function fun at 0x109690ea0>, <function fun at 0x109690d90>, <function fun at 0x10968e048>]
# 5
# 5
# 5
# 5
# 5

若想输出:1,2,3,4,5   :闭包在返回时,它的所有变量已经固定了,形成一个封闭的对象,

_list=[]
for i in range(5):
def func(i):
def f_closure(a):
return i+a
return f_closure
_list.append(func(i))
print (_list)
for f in _list:
print (f(1))

# [<function func.<locals>.f_closure at 0x109690e18>, <function func.<locals>.f_closure at 0x109690c80>, <function func.<locals>.f_closure at 0x109690d08>, <function func.<locals>.f_closure at 0x109690ea0>, <function func.<locals>.f_closure at 0x109690d90>]
# 1
# 2
# 3
# 4
# 5

 

 闭包案例:

def who(name):
def do(what):
print (name,'say',what)
return do





teddy=who('teddy')
angel=who('angel')

teddy('yyy')
angel('ggg')

     

日志记录器:

import logging
def log_header(logger_name):
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s [%(name)s] %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S')
logger = logging.getLogger(logger_name)

def _logging(something, level):
if level == 'debug':
logger.debug(something)
elif level == 'warning':
logger.warning(something)
elif level == 'error':
logger.error(something)
else:
raise Exception(' oh ,i dont know what you want to do!')

return _logging


p_1_logging = log_header('project_1')
p_2_logging = log_header('project_2')


def project_1():
p_1_logging('yyy', 'debug')
p_1_logging('bbb', 'warning')
p_1_logging('ccc', 'error')


def project_2():
p_2_logging('qqq', 'debug')
p_2_logging('eee', 'warning')
p_2_logging('yyy', 'error')

project_1()
project_2()

输出:

2020-05-03 11:31:27 [project_1] DEBUG yyy
2020-05-03 11:31:27 [project_1] WARNING bbb
2020-05-03 11:31:27 [project_1] ERROR ccc
2020-05-03 11:31:27 [project_2] DEBUG qqq
2020-05-03 11:31:27 [project_2] WARNING eee
2020-05-03 11:31:27 [project_2] ERROR yyy

心有猛虎,细嗅蔷薇

举报

相关推荐

0 条评论