nonlocal关键字

# 作用:将 L 与 E(E中的名字需要提前定义) 的名字统一

# 应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值

# 案例:

def outer():
   num = 10
   print(num)  # 10
   def inner():
       nonlocal num
       num = 20
       p77rint(num)  # 20
   inner()
   print(num)  # 20

开放封闭原则:不改变调用方式与源代码上增加功能

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

装饰器

# 把要被装饰的函数作为外层函数的参数通过闭包操作后返回一个替代版函数
# 被装饰的函数:fn
# 外层函数:outer(func) outer(fn) => func = fn
# 替代版函数: return inner: 原功能+新功能

def fn():
   print("原有功能")

# 装饰器
def outer(tag):
   def inner():
  tag()
       print(新增功能")
   return inner
fn = outer(fn)              
             
fn()

@语法糖: @外层函数

def outer(f):
   def inner():
  f()
       print("新增功能1")
   return inner
             
def wrap(f):
   def inner():
  f()
       print("新增功能2")
   return inner              

@wrap  # 被装饰的顺序决定了新增功能的执行顺序
@outer  # <==> fn = outer(fn): inner      
def fn():
   print("原有功能")

有参有返的函数被装饰

def check_usr(fn):  # fn, login, inner:不同状态下的login,所以参数是统一的
   def inner(usr, pwd):
       # 在原功能上添加新功能
       if not (len(usr) >= 3 and usr.isalpha()):
           print('账号验证失败')
           return False
       
       # 原有功能
       result = fn(usr, pwd)
       
  # 在原功能下添加新功能
       # ...
       
       return result
  return inner


@check_usr
def login(usr, pwd):
   if usr == 'abc' and pwd =='123qwe':
       print('登录成功')
       return True
   print('登录失败')
   return False

# 总结:
# 1.login有参数,所以inner与fn都有相同参数
# 2.login有返回值,所以inner与fn都有返回值

"""
inner(usr, pwd):
  res = fn(usr, pwd) # 原login的返回值
  return res


login = check_usr(login) = inner

res = login('abc', '123qwe') # inner的返回值
"""

装饰器最终写法


def wrap(fn):
   def inner(*args, **kwargs):
       print('前增功能')
       result = fn(*args, **kwargs)
       print('后增功能')
       return result
   return 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 True

fn1()
fn2(10, 20)
fn3()
fn4(10, x=20)

带参装饰器:了解

# 了解
def outer(input_color):
   def wrap(fn):
       if input_color == 'red':
           info = '\033[36;41mnew action\33[0m'
       else:
           info = 'yellow:new action'

       def inner(*args, **kwargs):
           pass
           result = fn(*args, **kwargs)
           print(info)
           return result
       return inner
   return wrap  # outer(color) => wrap


color = input('color: ')
@outer(color)  # @outer(color) ==> @wrap # func => inner
def func():
   print('func run')

func()

登录认证功能

is_login = False  # 登录状态

def login():
   usr = input('usr: ')
   if not (len(usr) >= 3 and usr.isalpha()):
       print('账号验证失败')
       return False
   pwd = input('pwd: ')
   if usr == 'abc' and pwd =='123qwe':
       print('登录成功')
       is_login = True
   else:
       print('登录失败')
       is_login = False


# 完成一个登录状态校验的装饰器
def check_login(fn):
   def inner(*args, **kwargs):
       # 查看个人主页或销售功能前:如果没有登录先登录,反之可以进入其功能
       if is_login != True:
           print('你未登录')
           login()
       # 查看个人主页或销售
       result = fn(*args, **kwargs)
       return result
   return inner

# 查看个人主页功能
@check_login
def home():
   print('个人主页')

# 销售功能
@check_login
def sell():
   print('可以销售')

home()

Day 12 开放封闭原则,装饰器初识的更多相关文章

  1. day12 十二、开放封闭、装饰器

    一.nonlocal关键词 # global # num = # def fn(): # global num # L>G 将局部的名字与全局统一 # num = # fn() # print( ...

  2. 【Python入门学习】闭包&装饰器&开放封闭原则

    1. 介绍闭包 闭包:如果在一个内部函数里,对在外部作用域的变量(不是全局作用域)进行引用,那边内部函数被称为闭包(closure) 例如:如果在一个内部函数里:func2()就是内部函数, 对在外部 ...

  3. Python——day12 nonlcoal关键字、装饰器(开放封闭原则、函数被装饰、最终写法)

    一.nonlocal关键字 1.作用:将L与E(E中的名字需要提前定义)的名字统一 2.应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值 def outer(): num=10 print ...

  4. 装饰器和"开放-封闭"原则

    装饰器和"开放-封闭"原则 "开放-封闭"原则 软件开发中的"开放-封闭"原则,它规定已经实现的功能代码不应该被修改,但可以被扩展,即: 封 ...

  5. day11.装饰器初识

    1.开放封闭原则 原则: 开放封闭原则,对扩展是开放的,对修改是封闭的. 封版概念:当写好一个功能以后,就不可以再修改此函数,避免下面一系列的调用产生错误. 因此产生了装饰器 2.装饰器形成过程 我们 ...

  6. DAY 13 开放封闭原则

    装饰器: 即是用一个函数去拓展另一个函数,同时遵循开放封闭原则 开放封闭原则 对修改关闭,对拓展开放 不允许修改源代码以及调用方式 以下是无参函数的基本格式 def outer(func): def ...

  7. python 装饰器-初识

    一.装饰器的形成过程 1.函数无参数,无返回值 import time def f1(): # 无参数,无返回值 time.sleep(1) print("Hello, World!&quo ...

  8. python 全栈开发,Day11(函数名应用,闭包,装饰器初识,带参数以及带返回值的装饰器)

    一.函数名应用 函数名是什么?函数名是函数的名字,本质:变量,特殊的变量. 函数名(),执行此函数. python 规范写法 1. #后面加一个空格,再写内容,就没有波浪线了. 2.一行代码写完,下面 ...

  9. (转) 面向对象设计原则(二):开放-封闭原则(OCP)

    原文:https://blog.csdn.net/tjiyu/article/details/57079927 面向对象设计原则(二):开放-封闭原则(OCP) 开放-封闭原则(Open-closed ...

随机推荐

  1. 文件编码检测.ZC一些资料(包含java的)

    1.IMultiLanguage3 或者 IMultiLanguage2 1.1.怎么判断XML 的编码格式(UTF-8或GB2312等)-CSDN论坛.html(https://bbs.csdn.n ...

  2. win8获取保存的wlan密码方法

    使用netsh wlan show profile * key=clear 方法查找所有的保存的wifi 使用 netsh wlan show profile name="wifi名字&qu ...

  3. 『Python CoolBook』C扩展库_其五_C语言层面Python库之间调用API

    点击进入项目 一.C层面模块添加API 我们仍然操作如下结构体, #include <math.h> typedef struct Point { double x,y; } Point; ...

  4. javascript中的词法分析

    词法分析 JavaScript中在调用函数的那一瞬间,会先进行词法分析. 词法分析的过程: 当函数调用的前一瞬间,会先形成一个激活对象:Avtive Object(AO),并会分析以下3个方面: 1: ...

  5. ZCRM_AU_MAIL

    FUNCTION ZCRM_AU_MAIL. *"---------------------------------------------------------------------- ...

  6. vue配置编译本地打开dist/index.html文件

    项目完成后npm run build会生成dist文件,此时直接将dist文件发布到线上即可,若想本地打开dist/index.html可看,一般页面为空,或者报错找不到css和js文件,则需要更改一 ...

  7. 封装一个函数,在ThinkPHP中一定程度上取代success和error

    1.下载jq2.下载layer3.根据自己的项目配置,将上述2文件放到样式目录中4.在Application/Common/function.php中添加如下代码function msg($msg,$ ...

  8. linux c使用socket进行http 通信,并接收任意大小的http响应(一)

    如何进行http通信呢?我们打开任意一个浏览器,按F12,再选择网络,然后打开任意一个网站,我们就可以看到浏览器和网站通信的过程 如下图: 然后,我们任意点击一条记录,可以看到 然后,查找http协议 ...

  9. mybatis oracle:批量操作(增删改查)

    此文主要是讲mybatis在连接oracle数据库时的一些批量操作,请各位对号入座 (最后回来补充一下,所有都是在Spring+MVC的框架下实现的) 不废话,上代码: 1.批量插入(网上很多,是针对 ...

  10. kafka consumer重复消费问题

    在做分布式编译的时候,每一个worker都有一个consumer,适用的kafka+zookeep的配置都是默认的配置,在消息比较少的情况下,每一个consumer都能均匀得到互不相同的消息,但是当消 ...