一、函数的嵌套定义

  1. # 概念:在一个函数的内部定义另一个函数
  2.  
  3. # 为什么要有函数的嵌套定义:
  4. # 1)函数fn2想直接使用fn1函数的局部变量,可以讲fn2直接定义到fn1的内部,这样fn2就可以直接访问fn1的变量
  5. # 2)函数fn2名字就变成fn1的局部变量了,正常只能在fn1中使用,想在外部使用,可以讲fn2函数对象作为fn1函数的返回值
  6. # 3)在外部也用同名的变量fn2来接收fn1函数的执行结果(fn1函数的返回值),那么fn2也就是可以在外部被调用

二、global与nonlocal关键字

  1. global关键字
  2. # 作用:将局部的变量提升为全局变量
  3. # 1.全局没有同名变量,直接提升局部变量为全局变量
  4. # 2.有同名全局变量,就是统一全局与局部的同名变量
  5. # -- 如果局部想改变全局变量的值(发生地址的变化),可以用global声明该变量
  6.  
  7. # num = 888
  8. def fn1():
  9. global num
  10. # print(num)
  11. # 没有global修饰,num就是自己局部的变量
  12. # 有global修饰,num就是全局的num,全局中只能出现一个num,如果出现了值的改变,大家一起变
  13. num = 666
  14. def fn2():
  15.  
  16. fn1()
  17. fn2()
  1. nonlocal关键字
  2. # 作用:将局部的变量提升为嵌套局部变量
  3. # 1.必须有同名嵌套局部变量,就是统一嵌套局部与局部的同名变量
  4. # -- 如果局部想改变嵌套局部变量的值(发生地址的变化),可以用nonlocal声明该变量
  5.  
  6. def outer():
  7. num = 888
  8. def inner():
  9. nonlocal num
  10. num = 666
  11.  
  12. inner()
  13.  
  14. outer()

三、开放封闭原则

  1. # 开放封闭原则:在不修改源代码与调用方式的情况下为函数添加新功能
  2. # 开放:有些事,你可以干 - 拓展功能
  3. # 封闭:有些事,你干不了 - 两个原则
  4. # 1.不能修改源代码 - 1.无权修改 2.功能不特有 3.修改的位置多个,需要一一修改
  5. # 2.不能修改原函数的调用方式 - 修改调用方式的弊端,原项目的所有函数调用都要修改

四、装饰器

  1. # 装饰器:满足开放封闭原则的一个闭包应用
  2.  
  3. # @outer语法来调用outer,规定传入被装饰的函数对象,所以参数固定为一个,接受被装饰的函数对象
  4. def outer(func):
  5. # 不能确定被装饰的函数的参数:来者不拒,用可边长来接受
  6. def inner(*args, **kwargs):
  7. pass # 新功能位
  8. res = func(*args, **kwargs) # 解压带给原功能
  9. pass # 新功能位
  10. return res
  11. return inner
  12.  
  13. # 使用装饰器(outer),得到新功能(inner)
  14.  
  15. # 用被装饰的函数名去接受装饰器的执行结果,调用装饰器时传入被装饰的函数对象
  16. @outer # fn = outer(fn) = inner
  17. def fn(): pass
  18.  
  19. # 表面感觉调用的是原函数,本质调用的是闭包(inner),使用fn调用和fn定义及inner需要参数统一
  20. fn()
  1. 装饰器的应用
  2. def outer(func):
  3. def inner(*args, **kwargs):
  4. res = func(*args, **kwargs)
  5. return res
  6. return inner
  7.  
  8. def check_user(func):
  9. def inner(*args, **kwargs):
  10. # 账号的验证功能
  11. user = args[0] # type: str
  12. if not (user.isalpha() and len(user) >= 3):
  13. print('账号不合法')
  14. return False
  15.  
  16. res = func(*args, **kwargs)
  17. return res
  18. return inner
  19.  
  20. def check_pwd(func):
  21. def inner(*args, **kwargs):
  22. pwd = args[1]
  23. if len(pwd) < 3:
  24. print('密码不合法')
  25. return False
  26.  
  27. res = func(*args, **kwargs)
  28. return res
  29. return inner
  30.  
  31. def format_return(func):
  32. def inner(*args, **kwargs):
  33. res = func(*args, **kwargs)
  34. if res:
  35. return '登录成功'
  36. return '登录失败'
  37. return inner
  38.  
  39. # 登录的原功能
  40.  
  41. @format_return
  42. @check_user
  43. @check_pwd
  44. def login(user, pwd):
  45. ':
  46. return True
  47. return False
  48.  
  49. user = input('user: ')
  50. pwd = input('pwd: ')
  51. res = login(user, pwd)
  52. print(res)
  53.  
  54. # 执行过程:调用login => 进入第一个装饰器(format_return)的inner => 进入第二个装饰器(check_user)的inner => 进入第三个装饰器(check_pwd)的inner => 开始返回,从第三个返回到第二个再返回到第一个,最后返回到外界调用的位置

初学python之路-day13的更多相关文章

  1. Python之路Day13

    day13主要内容:JavaScript.DOM.jQuery 武Sir blog:http://www.cnblogs.com/wupeiqi/articles/5369773.html JavaS ...

  2. 初学python之路-day12

    本篇补上字符串的比较:按照从左往右比较每一个字符,通过字符对应的ascii进行比较 一.函数默认值的细节 # 如果函数的默认参数的默认值为变量,在所属函数定义阶段一执行就被确定为当时变量存放的值 a ...

  3. 初学python之路-day10

    基础部分先告一段落,今天开始学习函数. 一.函数:完成 特定 功能的代码块,作为一个整体,对其进行特定的命名,该名字就代表函数         -- 现实中:很多问题要通过一些工具进行处理 => ...

  4. 初学python之路-day08前期总结

    # 1# 计算机原理:控制器 运算器 存储器 input设备 output设备 IO流# 三大核心:CPU 内存 硬盘 # 内存分布:栈区 与 堆区# 如二进制与十进制的转换,如1111转成十进制为1 ...

  5. 初学python之路-day08

    #学习了编码后,还要了解三种字符串.# 一.# 普通字符串:u''以字符作为输出单位,# print(u'abc') # 用于显示abc# # 二进制字符串:b'' 二进制字符串以字节作为输出单位# ...

  6. 初学python之路-day07-字符编码

    今天的博客主要关于字符编码,并对前几天学习的数据类型做些总结. 学习字符编码的目的:解决乱码问题. 应用程序打开文本文件的三步骤  1.打开应用程序  2.将数据加载到内存中  3.cpu将内存中的数 ...

  7. 初学python之路-day04

    每天一篇总结,今天学习的是有关于流程控制的知识. 流程控制,顾名思义,在计算机运行中,程序是被某种控制方式按照某种流程或者规律来执行的.而python程序的运行,肯定也是按照某种规律在执行.这些规律可 ...

  8. 初学python之路-day03

    我在前面的文章提到了变量的概念,这里详细介绍下变量的命名.变量名,只能是字母.数字及下划线 "_" 任意组成,而且不能以数字开头.在命名变量时,尽量避免与系统关键词重名,如:'an ...

  9. 初学python之路-day02

    python,诞生于1989年的圣诞,Guido van Rossum为了打发无聊,因此发明了python,并且开放了其源代码,使得这门语言在随后的几十年的发展的越来越广.现今,2.x版本已经在2.7 ...

随机推荐

  1. Webstorm的一些常用快捷键

    ctrl+/ 单行注释ctrl+shift+/块注释Ctrl+X 删除行Ctrl+D 复制行Ctrl+B 快速打开光标处的类或方法Ctrl+F 查找文本Ctrl+R 替换文本ctrl+shift+ + ...

  2. 初始ajax技术

    一.AJAX是啥? 1.页面无需刷新,异步请求. 2.为什么使用ajax? 原因: 1传统模式  需要将请求发送到服务器,服务器经过业务处理,返回一个页面给客户端.这样做,会很浪费资源. 2.ajax ...

  3. tomcat server.xml结构

    所有xml文件使用的文件头 <?xml version='1.0' encoding='utf-8'?> 2 <Server port="8005" shutdo ...

  4. freeCodeCamp中一些有趣的方法

    1. 过滤对象(找到数组中(collection)与之(source)匹配对象,过滤掉数组中(collection)不匹配对象) function where(collection, source) ...

  5. Linux系统中硬链接和软链接(符号链接)的区别

    首先是创建链接的命令 ln file link //创建硬链接 ln -s item link //创建软链接 区别 硬链接 硬链接是一开始Unix创造链接的方式,而软连接就更现代一点.创建硬链接的时 ...

  6. python学习day20 面向对象(二)类成员&成员修饰符

    1.成员 类成员 类变量 绑定方法 类方法 静态方法 属性 实例成员(对象) 实例变量 1.1实例变量 类实例化后的对象内部的变量 1.2类变量 类中的变量,写在类的下一级和方法同一级. 访问方法: ...

  7. 微信小程序之:wepy框架

    1.介绍 WePY 是 腾讯 参考了Vue 等框架对原生小程序进行再次封装的框架,更贴近于 MVVM 架构模式, 并支持ES6/7的一些新特性. 2.使用 npm install -g wepy-cl ...

  8. (模拟) codeVs1160 蛇形矩阵

    题目描述 Description 小明玩一个数字游戏,取个n行n列数字矩阵(其中n为不超过100的奇数),数字的填补方法为:在矩阵中心从1开始以逆时针方向绕行,逐圈扩大,直到n行n列填满数字,请输出该 ...

  9. Apache Hadoop 2.9.2 的归档案例剖析

    Apache Hadoop 2.9.2 的归档案例剖析 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   能看到这篇文章说明你对NameNode 工作原理是有深入的理解啦!我们知道 ...

  10. SpringCloud笔记六:Hystrix

    目录 Hystrix是什么? Hystrix服务熔断 新建Hystrix项目 修改yml Maven的pom.xml添加hystrix引用 修改Controller Hystrix服务降级 修改api ...