今日内容

  • 1.函数对象

  • 2.名称空间与作用域

  • 3.函数的嵌套调用与闭包

  • 4.装饰器

一、函数对象

1.1 定义

函数名存放的就是函数地址,所以函数名也就是对象,称之为函数对象

1.2 函数对象的应用

1.可以直接被引用
2.可以当作函数参数传数
3.可以作为函数的返回值
4.可以作为容器类型的元素
def fn():num = 10print('fn function run')# 直接被引用
func = fn
fn()
func()

案例:四则运算

def add(n1, n2):return n1 + n
def sub(n1, n2):  # subtraction 减法return n1 - n2
def mul(n1, n2):  # multiplication 乘法return n1 * n2
def div(n1, n2):  # division 除法return n1 / n2method_map = {'add': add,'sub': sub,'mul': mul,'div': div
}def computed(fn):if fn in method_map:return method_map[fn]else:return add
def func():cmd = input("方法名:")method = computed(cmd)result = method(100, 20)print(result)
func()

二、名称空间

2.1 三种名称空间

built-in:内置名称空间,系统级,一个,随解释器执行而产生,解释器停止而销毁
global:全局名称空间,文件级,多个,随所属文件加载而产生,文件运行完毕而销毁
local:局部名称空间,函数级,多个,随所属函数执行而产生,函数执行完毕而销毁注:加载顺序:built-in > global > local
num = 10
def fn2():num = 20print("this is fn2", num)def fn3():num = 30print("this is fn3", num)fn2()  # this is fn2 20
fn3()  # this is fn3 30
print(num)  # 10

三、作用域

3.1 LEGB

不同作用域之间名字不冲突,以达到名字的重用
直接查找顺序: Local -> Enclosing -> global -> built-inbuilt-in : 内置作用域,所有函数
global:全局作用域,当前文件所有函数
enclosing:嵌套作用域,当前函数
local:局部作用域
len = 10
def outer():len = 20def inner():len = 30print('1', len)inner()print('2', len)outer()
print('3', len)  # 10 global --> built-in
del len
print('4', len)  # len地址--》built-in
nonlocal:作用:将L与E的名字统一(E中的名字需要提前定义)应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值案例:def outer():num = 10print(num)  # 10def inner():nonlocal numnum = 20print(num)  # 20inner()print(num)  # 20outer()
# 第三行打印的 num ,是上一行定义的num
# 由于第五行用 nonlocal 声明了,所以inner里面的num和outer里面定义的num指代的是同一个东西# 第七行打印的 num ,在第六行重新赋值(num指向的内存地址发生改变)

四、函数嵌套

将函数直接定义到另一个函数内部就可以使用外部函数中的名字
def outer():num = 20def inner():print(num)  # inner 可以直接使用outer中的名字inner()outer()

五、闭包

函数嵌套(格式稍作改良)
inner : 可以使用outer的局部变量
def outer():num = 10def inner:print(num)return inner
fn = outer()
fn()
# 案例一:外部函数可以为闭包传递参数
import time
def download():print('开始下载...')time.sleep(2)print('完成下载...')data = ""outer(data)
# 传参
def outer(data):def inner():# 保存,播放,删除等操作print("闭包打印:", data)inner()
download()
# 案例二:延迟执行
import requests
def outer(url):def get_html():html = requests.get(url)print(html.text)return get_html
# 先预定义多个爬虫方法,爬页面操作并未执行
baidu = outer('https://www.baidu.com')
python = outer('https://www.python.org')
sina = outer('https://www.sina.com.cn')
# 什么时候想爬什么页面就调用指定页面的爬虫方法
baidu()
sina()

2019.04.02 更新

四、装饰器

4.1 什么是装饰器

名字上来看,就是用来装饰的东西
从使用上来看,用来‘装饰’其他函数的函数,可以在原先函数功能基础上添加新的功能

4.2 开放封闭原则

在不改变调用方式和源码上增加功能
1.不能修改被装饰对象(函数)的源代码(封闭)
2.不能更改被修饰对象(函数)的调用方式,且能达到增加功能的效果(开放)

4.3 装饰器语法格式

def outer(fn):def inner(*args,**kwargs):#实现的功能result = fn(*args,**kwargs)#实现的功能return resultreturn inner

4.4 案例们

4.4.1 实现原理
def fn():print("这是最初的函数!")
# 装饰器
def outer(func):def inner():func()print("打印一行给你看看,这就是添加的新功能!")return inner
fn = outer(fn)
fn()# 打印结果:
# 这是最初的函数!
# 打印一行给你看看,这就是添加的新功能!分析:
函数的执行顺序:1.python 程序是从上往下执行的,程序先读第1,4行程序(不执行),2.执行第9行代码,但是先从右侧开始执行,3.执行outer(fn),程序跳转到第4行,读入inner函数,跳转到8行,执行return,将inner地址返回4.返回的inner地址被fn接收,执行最后一行代码5.执行的fn()相当于执行inner()函数,也就是执行inner函数的函数体,由func()和其下一行组成6.其中第6行就是原先的函数 fn(),下一行就是增加的功能7.整个程序就实现了在原有基础函数不改变的情况下,增加了新的功能# 外层函数
def outer(f):def inner():f()print("这里是新增加的功能!11")return inner
def wrap(f):def inner():f()print("这里也是新增加的功能!22")return inner
@wrap
@outer
def fn():print("这里是本来的功能!")fn()# 执行结果:
# 这里是本来的功能!
# 这里是新增加的功能!11
# 这里也是新增加的功能!22分析:
多个装饰器同时装饰同一个函数,可以理解成 俄罗斯套娃 的形式,
谁离被装饰的函数越近,谁就先执行装饰任务"""
# 有参数有返回值的函数被装饰
"""
def check_user(fn):def inner(usr, pwd):  # inner == login# 在原功能的基础上添加新功能# 如果名字长度超过 3 并且  名字是纯字母数字if not (len(usr) >= 3 and usr.isalpha()):print("账号验证失败!")return False# 满足条件情况下,执行原有的功能result = fn(usr, pwd)return resultreturn inner@check_user   # login = check_user(login)
def login(usr,pwd): if usr == 'abc' and pwd =='123qwe':print('登录成功!')return Trueprint('登录失败!')return Falselogin('abc', '123qwe')  # 应该先看最下面这一条执行的函数总结:1.login有参数,所以inner与fn都有相同的参数2.login有返回值,所以inner与fn都有返回值"""
# 装饰器最终写法
"""
def wrap(fn):def inner(*args, **kwargs):print('前增功能')result = fn(*args, **kwargs)print('后增功能')return resultreturn inner@wrap
def fn1():print('fn1的原有功能')
@wrap
def fn2(a, b):print('fn2的原有功能')
@wrap
def fn3():print('fn3的原有功能')return True
@wrap
def fn4(a, *, x):print('fn4的原有功能')return Truefn1()
fn2(10, 20)
fn3()
fn4(10, x=20)"""
# 带参装饰器
"""
def outer(input_color):def wrap(fn):if input_color == 'red':info = '\033[36;42m new action \033[0m'else:info = 'yellow:new action'def inner(*args, **kwargs):passresult = fn(*args, **kwargs)print(info)return resultreturn innerreturn wrap  # outer(color) => wrapcolor = input('color: ')@outer(color)  # @outer(color) ==> @wrap  # func => inner
def func():print('func run')
func()"""
# 案例
# 登录认证功能
"""
is_login = Falsedef login():usr = input('usr: ')if not (len(usr) >= 3 and usr.isalpha()):print('账号验证失败!')return Falsepwd = input('pwd: ')if usr == 'abc' and pwd == '123qwe':print('登录成功!')is_login = Trueelse:print('登录失败!')is_login = False# 完成一个登录状态验证的装饰器
def check_login(fn):def inner(*args,**kwargs):if is_login != True:print("你未登录!")login()# 执行被装饰的函数功能result = fn(*args,**kwargs)return resultreturn inner# 查看个人主页功能
@check_login
def home():print('个人主页')# 销售功能
@check_login
def sell():print('清仓大甩卖!')# 测试函数
home()

转载于:https://www.cnblogs.com/xt12321/p/10640323.html

Python函数基础3 函数对象、名称空间、装饰器相关推荐

  1. python函数的全局、局部名称空间及作用域

    """ a = 1 def func(): return func() 开辟一个-全局名称空间(当前py文件),将这些对应关系储存在里面,函数是储存成func:funct ...

  2. python类的构造方法名称_搞懂Python的类和对象名称空间

    代码块的分类 python中分几种代码块类型,它们都有自己的作用域,或者说名称空间:文件或模块整体是一个代码块,名称空间为全局范围 函数代码块,名称空间为函数自身范围,是本地作用域,在全局范围的内层函 ...

  3. Python编程基础:函数的使用

    Python编程基础:函数的使用 文章目录 Python编程基础:函数的使用 一.前言 二.我的环境 三.函数的定义与调用 四.传递实参 1.位置实参 2.关键字实参 3.默认值 4.可变长度参数 5 ...

  4. python绘图实例-Python matplotlib基础绘图函数示例

    原标题:Python matplotlib基础绘图函数示例 Pyplot基础图标函数: 函数 说明 plt.plot(x,y,fmt,-) 绘制一个坐标图 plt.boxplot(data,notch ...

  5. python 函数结果缓存一段时间的装饰器

    把函数结果缓存一段时间,比如读取一个mongodb,mongodb中的内容又在发生变化,如果从部署后,自始至终只去读一次那就感触不到变化了,如果每次调用一个函数就去读取那太频繁了耽误响应时间也加大了c ...

  6. SIGIA_4P python学习 列表 字典 集合 面对对象编程 闭包 装饰器 函数式编程 作用域 异常处理

    SIGIA_4P python学习 列表 字典 集合 面对对象编程 闭包 装饰器 函数式编程 作用域 异常处理 本文连接 简介 SIGIA_4P 网址 a. 课程OKR Objectives and ...

  7. python grpc unary call错误_python的黑魔法-装饰器

    python的装饰器 装饰器 简单的来说就是函数的函数,在执行目标函数时,先执行装饰器函数,很像HOOk 简单的装饰器 实现一个打印日志的装饰器 def myLogger(func):def wrap ...

  8. 饮冰三年-人工智能-Python-16Python基础之迭代器、生成器、装饰器

    一:迭代器: 最大的特点:节省内存 1.1 迭代器协议 a:对象必须提供一个next方法, b:执行方法要么返回迭代中的下一项,要么抛弃一个Stopiteration异常, c:只能向后不能向前. 1 ...

  9. Python开发基础 day5 函数的定义与使用

    #coding:utf-8: # x='你' # u'hello'# print(x.encode('gbk')) # print(b'\xc4\xe3')# y=b'\xc4\xe3' # prin ...

最新文章

  1. linux mysql互为主从_mysql互为主从配置(双主模型)
  2. Java Web Start入门基础教程
  3. erlang精要(31)-尾递归版的翻转列表
  4. Oracle学习:视图与索引
  5. 7-227 PAT排名汇总 (25 分)
  6. Bootstrap 表格行的样式
  7. html typora 图片_Typora优化-适合不懂CSS代码的小白
  8. 使用XML及XSL生成简单HTML
  9. MyBatis3-以接口方式编程
  10. java并发编程实战读书笔记3
  11. 基于Matlab数字图像处理微表情情绪识别系统
  12. kei4的安装教程(附下载地址)
  13. 苹果x屏幕多少钱_xsmax闪屏,苹果xsmax换屏幕多少钱
  14. python hist2d_matplotlib可视化之hist直方图
  15. c#超火表白小程序(含代码教程)
  16. 微软输入法的使用技巧
  17. 无人机从零到一(组装、校准到起飞)
  18. Openlayers 图层的常用操作
  19. java 使用FileAlterationMonitor监控目录中的文件
  20. 为什么360浏览器兼容模式文档模式默认以ie7标准渲染

热门文章

  1. linux下jtag命令,[转载]LINUX内核调试过程(使用OpenJtag + OpenOCD)
  2. php 类定义抽象方法吗,如何理解php的抽象类跟抽象方法
  3. java四大模块_Spring框架七大模块
  4. 那是计算机房吗不它不是 英语,人教PEP版英语四年级下册Unit 1《My School》单元测试卷及答案.doc...
  5. java多线程安全解决方案_《Java多线程编程核心技术(第2版)》 —1.2.8 实例变量共享造成的非线程安全问题与解决方案...
  6. delphi 获取打印机默认纸张_如何设置一台打印机打印不同尺寸的纸张
  7. dnp服务器未响应,PTP时间戳精度
  8. linux系统 看com口,Linux如何设置com1口,让超级终端通过com1口进行登录
  9. mysql内核测试,MySQL 5.7内核复制中的一个小坑
  10. 机器人建模中移动关节如何建立坐标系_机器人标准DH建模法