函数-函数进阶-装饰器

想象一下:

你是一家视频网站的后端开发工程师,你们网站有以下几个版本:

def home():

  print("----首页----")

def america():

  print("----欧美专区----")

def japan():

  print("----日韩专区----")

def henan():

  print("----河南专区----")

视频刚上线初期,为了吸引用户,你们采取了免费政策,所有视频免费观看,迅速吸引了一大批用户,免费一段时间后,每天巨大的带宽费用公司承受不了了,所以准

备对比较受欢迎的几个板块收费,其中包括“欧美”和“河南”专区,你拿到这个需求后,想了想,想收费得先让其用户认证,认证通过后,再判定这个用是否是vip付费会员就可以了,

是vip就让看,不是vip就不让看就行了呗。你觉得这个需求很是简单,因为要对多给版块进行认证,那应该把认证功能提取出来单独写个模块,然后每个版块里调用就可以了,与是你轻轻的就实现了下面的功能。

# -*-coding:utf-8-*-

user_status = Fales #用户登录了就把这个改成True

def login()

  _username = "alex" #假装这是DB里存的用户信息

    _password = "abc!23" #假装这是DB里存的用户信息

  global user_status

  if user_status == False:

    username = input("user:")

    password = input("password")

    if username == _username and password == _password:

      print("welcome login...")

      user_status = True

    else:

      print("wrong username or password!")

  else:

    print("用户已登陆,验证通过。。。")

def home():

  print("----首页----")

def america():

  login() #执行前加上验证

  print("----欧美专区----")

def japan():

  print("----日韩专区----")

def henan():

  login() #执行前加上验证

  print("----河南专区----")

home()

america()

henan()

此时你信心满满的把这个代码提交给你的TEAM LEADER审核,没成想,没过5分钟,代码就呗打回来了,TEAM LEADER 给你反馈是,我现在有很多模块需要加认证

模块,你的代码虽然实现了功能,但是需要更改需要加认证的各个模块的代码,这直接违反了软件开发中的一个原则“开放-封闭”原则,简单来说,它规定已经实现的功能

代码不允许被修改,但可以被扩展,既:

。封闭:已实现的功能代码块不应该被修改

。开放:对现有功能的扩展开放

这个原则你还是第一次听说,我擦,再次感受了自己这个野生程序员与正规军的差距,BUT ANYWAY,老大要求的这个怎么实现呢?如何在不改原有功能代码的情况下

加上认证功能呢?你一时想不出思路,只好带着这个问题回家继续憋,媳妇不在家,去隔壁老王家串门了,你正好落的清净,一不小心就想到了解决方案,不改源代码可以呀。

你师从沙河金角大王时,记得他教过你,高阶函数,就是把一个函数当作一个参数传给另一个函数,当时大王说,有一天,你会用到它的,没想到这时这个知识点突然从脑子里蹦出来了,

我只需要写一个认证方法,每次掉哟个需要验证的功能时,直接把这个功能的函数名当作一个参数传给我的验证模块不就行了么,哈哈,机智如我,如是你啪啪啪改写了值卡的代码。

# -*-coding:utf-8-*-

user_status = Fales #用户登录了就把这个改成True

def login(func)

  _username = "alex" #假装这是DB里存的用户信息

    _password = "abc!23" #假装这是DB里存的用户信息

  global user_status

  if user_status == False:

    username = input("user:")

    password = input("password")

    if username == _username and password == _password:

      print("welcome login...")

      user_status = True

    else:

      print("wrong username or password!")

  else:

    print("用户已登陆,验证通过。。。")

  if user_status:

    func()

def home():

  print("----首页----")

def america():

  login() #执行前加上验证

  print("----欧美专区----")

def japan():

  print("----日韩专区----")

def henan():

  login() #执行前加上验证

  print("----河南专区----")

login(america)

login(henan)

你很开心,终于实现了老板的要求,不改变原功能代码的前提下,给功能加上了验证,此时,媳妇回来了,后面还跟着老王,你两家关系非常号,老王经常来串门,老王也是码农,你跟他分享了你写的代码,兴奋的等他看完,夸奖你NB,没想成,老王看后,并没有夸你,抱起你的儿子,笑笑说,你这个代码还是改改吧,要不然会被开除的,WHAT?会开出,明明实现了功能呀,老王讲,没错,你功能是实现了,但是你又犯了一个大忌,什么大忌?

你改变了调用方式呀,想一想,现在每个需要认证的模块,都必须调用你的login()方法,并把自己的函数名传给你,人家之前可不是这么调用的,试想,如有100给模块需要认证,那这100给模块都得更改调用方式,这么多模块肯定不止是一个人写的,让每个人再去修改调用方式才能加上认证,你会被骂死。。。

你觉得老王说的对,但问题是,如何即不改变原功能代码,又不改变原有调用的方式,还能加上认证?你苦思了一会,还是想不出,老王在都你的儿子玩,你说,老王呀,块给我点思路,实在想不出来,老王背对着你问,

老王:学过匿名函数没?

你:学过学过,就是lambda嘛

老王:那lambda 与正常函数的区别是什么?

你:你最直接的区别是,正常函数定义是需要写名字,但lambda不需要

老王:没错,那lambda 定好后,为了多次调用,可以也给它命给名?

你:可以呀,可以写成 plus =lambda x:x+1类似这样,以后再调用plus就可以了,但这样不就失去了lambda的意义了,明明人家匿名函数,你取名字还有什么作用呢?

老王:我不是要跟你他的医院,我想通过这个让你明白一个事实。

说着,老王拿起你儿子的画板,在上面写了一下一下代码:

  def plus(n)

    return n+1

plus2 = lambda x:x+1

老王:上面这两种写法是不是代表(同样的意思)

你:是的

老王:没啥,只想高速你,给函数赋值变量名就像def func_name 是一样的效果,如下面的plus(n)函数,你调用时可以用plus名,还可以再起个其他名字

calc = plus

calc(n)

你明白我想传达什么意思了么?

你:。。。。。。。。这。。。。。嗯。。。。不太。。。。明白。。。

老王:。。。。。这。。。。。。呵呵。。。。好吧。。。。那我在给你点一下,你之前写的下面这段调用 认证的代码

home()

login(america) #需要验证就调用login,需要验证功能 当做一个参数传给login

# home()

# america()

login(henan)

你之所改变了调用方式,是因为用户每次调用时需要执行login(henan),类似的。其实稍一改就可以了呀。

home()

america = login(america) # 你在这里相当于把america 这个函数替换了

henan = login(henan)

#那用户调用时依然写

america()

但问题在于,还没等用户调用,你的america = login(america)就会先自己把america执行了呀。。。 你应该等我用户调用的时候再执行

你看。。。

老王:哈哈,你说的没错,这样搞会出现这个问题?但你想想有没有解决办法呢?

你:我擦,你指的思路呀,大哥。。。我哪知道下一部怎么走。。。

原文地址:https://www.cnblogs.com/kingforn/p/10916416.html

时间: 2024-11-07 19:05:10

函数-函数进阶-装饰器的相关文章

第四天 内置函数2 随机码 装饰器 迭代器、生成器 递归 冒泡算法 JSON

关于函数的return li = [11,22,33,44] def f1(arg): arg.append(55) li = f1(li) print(li) 因为li = f1(li) 实际赋值的是f1的return,那么在这种情况下函数f1并未定义return,所以默认返回None 因此li的值应该是none 如果是 li = [11,22,33,44] def f1(arg): arg.append(55) f1(li) print(li) 因为函数传递的参数实际是参数的引用,因此在函数

函数嵌套与装饰器

*应用场景,位置参数中代表将多个参数存入元祖,**将关键字参数传入字典 位置参数: 位置形参:必须被传值,一一对应 位置实参:按从左到右的顺序与形参一一对应 关键字参数:按照key=value形式指名道姓的为形参传值,可以完全不按照顺序 1.关键字实参必须在位置参数的后面 2.可以混用位置实参与关键字实参,但不能为同一个形参重复传值 默认参数: 形参有默认值 可变长参数 形参:*args,**kwargs将多余的参数分别封装成元祖与字典 实参:将args kwargs分别打散 什么是命名关键字参

Django视图函数函数之视图装饰器

FBV模式装饰器: 普通函数的装饰器(语法糖@) views.py 1 from django.shortcuts import render 2 3 def wrapper(f): 4 def inner(*args,**kwargs): 5 print("before") 6 ret=f(*args,**kwargs) 7 print("after") 8 return ret 9 return inner 10 11 @wrapper 12 def index

【Python基础】高阶函数+函数嵌套+闭包 ==装饰器

高阶函数+函数嵌套+闭包 == 装饰器 一 什么是装饰器 二 装饰器需要遵循的原则 三 实现装饰器知识储备 四 高阶函数 五 函数嵌套 六 闭包 七 无参装饰器 八 装饰器应用示例 九 超时装饰器 参考: https://www.cnblogs.com/linhaifeng/articles/6140395.html https://www.cnblogs.com/haiyan123/p/8387769.html 原文地址:https://www.cnblogs.com/XJT2018/p/11

python函数四(装饰器进阶)

一.开放封闭原则 1.对扩展是开放的 任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改.所以我们必须允许代码扩展.添加新功能. 2.对修改是封闭的 比如我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户. 装饰器完美的遵循了开放封闭原则. 二.函数的有用信息 def func(): ''' 本函数主要用于绘图,实时接收数据 :return:返回给前端某标签 ''' print(func.__doc

python 基础篇 11 函数进阶----装饰器

11. 前??能-装饰器初识本节主要内容:1. 函数名的运?, 第?类对象2. 闭包3. 装饰器初识 一:函数名的运用: 函数名是一个变量,但他是一个特殊变量,加上括号可以执行函数. ?. 闭包什么是闭包? 闭包就是内层函数, 对外层函数(非全局)的变量的引?. 叫闭包 可以使用_clesure_检测函数是否是闭包  返回cell则是闭包,返回None则不是 闭包的好处: 由它我们可以引出闭包的好处. 由于我们在外界可以访问内部函数. 那这个时候内部函数访问的时间和时机就不?定了, 因为在外部,

python函数三 (装饰器)

一.函数名(学名:第一类对象) 函数名本质上就是函数的内存地址.通俗点就是特殊的普通变量 def func(): print(111) func() print(func) # 结果: # 111 # <function func at 0x00000150713F6048> 1.可以被引用(即可以赋值给其他变量) def func(): print('in func') f = func f() # 结果: # in func 2.可以被当作容器类型的元素 def func(): print

5.初识python装饰器 高阶函数+闭包+函数嵌套=装饰器

一.什么是装饰器? 实际上装饰器就是个函数,这个函数可以为其他函数提供附加的功能. 装饰器在给其他函数添加功能时,不会修改原函数的源代码,不会修改原函数的调用方式. 高阶函数+函数嵌套+闭包 = 装饰器 1.1什么是高阶函数? 1.1.1函数接收的参数,包涵一个函数名. 1.1.2 函数的返回值是一个函数名. 其实这两个条件都很好满足,下面就是一个高阶函数的例子. def test1(): print "hamasaki ayumi" def test2(func): return t

打印函数运行时间的装饰器

1 import time 2 3 def timethis(func): 4 """ 5 测试函数运行花费时间的装饰器 6 """ 7 def wrapper(*args, **kwargs): 8 start = time.time() 9 result = func(*args, **kwargs) 10 end = time.time() 11 print("函数 %s 运行时间: %s" % func.__name_

Python学习笔记6-python函数补充、装饰器、模块

本文主要学习内容有 函数知识的补充 装饰器(无参.有参.非固定参数.有返回值) 函数知识的补充 稍后待续...