玩了一晚上王者,突然觉得该学习,然后大晚上的搞出来这道练习题,凌晨一点写博客(之所以这么晚就赶忙写是因为怕第二天看自己程序都忘了咋写的了),我太难了o(╥﹏╥)o

言归正传,练习题要求:构造类似京东的一个网站首页(超级简化),实现函数装饰器的设计(主要设计),装饰的内容为,无论添加什么商品进购物车,最终付款的时候都需要登录才能支付,且无论在哪个页面下登录过一次都不需要再次登录,即做一个函数装饰器,实现登录功能(装饰到所有商品界面)。

我的实现:商品分类页面进行函数话,即一个类别构造一个函数,选择商品类别即执行函数,至于函数的内容就是简单的打印下商品名称,毕竟重点在登录,商品类别函数内具体有什么不重要。当第一次登录时,可选择登录方式:京东或者微信,在项目文件夹中创建了两个txt文件,里面没啥东西,就一个TXT存一个字典,字典里面预设两个key当做用户名及密码。登录一次后再运行程序(我给设成自动的了),即选择其他商品类别,将不会再让登录验证。

具体实现效果图:

具体代码:

login_type = "jingdong"#用于初始化带参装饰器,然而我没用上
juge_login = False#用于判断登录状态,直接全局 def login(type):#装饰器为两层def,带参装饰器为三层def,但说实话,我的这个带参装饰器其实并没有在这个程序中起到什么作用,但提供了一个可用参数,我没用到,但这个参数是可以用的,可以做个判断加个功能啥的
def auth_method(fuction):
def really_login():
global juge_login
if(juge_login == False):
login_type = input('''请选择登录的方式:
1、京东
2、微信
''')
if(login_type == "1"):login_type = "jingdong"
if(login_type == "2"):login_type = "weixin"
username = input("请输入你的用户名:")
password = input("请输入你的密码:")
f = open(login_type,"r")#f.readline()返回的是一行,类型为str;f.readlines()返回的是所有行,返回类型是list(一行一个元素,因为我存了两个键用了一行,所以直接取第一个元素)
key = eval(f.readlines()[0])#虽然我存储的是字典形式的文本,但提取出来后只是长得跟字典一模一样的字符串,eval的功能就是将长得一模一样的str转为dict
for m,n in key.items():#遍历查找文本所有账户寻找匹配项
if(username == m and password == n):
print("登陆成功")
juge_login = True#置位 f.close()
if(juge_login == False):
print("用户名或密码错误,请重新输入:")
return really_login() fuction()#当登录完成或者登录过一次后,就不会执行上面的if判断(if判断含return,如果登不成功永远停留在登录上而无法执行下一步)
print("程序尚未完成,请选择继续测试功能:")
Start_main()#为了测试而专门放在这循环的,这个不是装饰的一部分,讲道理登录的装饰完就完了,这个可以加在main里搞个循环啥的,太懒了,就这样吧
return really_login#注意,返回的是函数(函数的内存地址,后面加上()是可以执行返回函数的,而不是结果(类似str,int等类型结果))
return auth_method @login(login_type)#@login() == @auth_method
def jiaju():
print('''请选择你要购买的商品:
1、海尔电冰箱
2、格力空调
3、席梦思床垫''') @login(login_type)#带参装饰,被装饰函数为@的下一行定义函数,用于装饰的函数为@后面紧跟的函数(带参函数略有不同)
def shipin():
print('''请选择你要购买的商品:
1、盼盼鸡味块
2、乐事薯片
3、伊利安慕希''') @login(login_type)
def yiwu():
print('''请选择你要购买的商品:
1、耐克球鞋
2、波司登棉袄
3、阿迪达斯帽子''') def Start_main():
print('''欢迎来到京东购物商城:
1、家具
2、食品
3、衣物''')
choose = input("请选择你要购买的类别:")
if(choose == "1"):
jiaju()
elif(choose == "2"):
shipin()
elif(choose == "3"):
yiwu()
else:print("输入错误,请输入商品类别前面的数字代码。") if __name__ == '__main__':#主函数调用开始界面函数(首页)
Start_main() 解析:装饰函数最大的特点在于返回值,返回的是函数本题(函数内存地址,相当于变量,指向的一块地址),而不是函数执行过后的结果,比如
def add(a,b):
return a+b
add与add(1,2)的区别在于什么?不是1,2带不带参数的区别,而是add是一个“变量”,指向一个内存地址,当访问(执行)这块地址时(执行方法为地址+());而add(1,2)是执行后返回的结果(无返回值为None),是动态的,会自己运行的。所以当return add时是返回add的内存地址,返回add()是返回add执行的结果,前者在返回值后面加上()就可以再次作为函数执行,后者是结果,加上()会报错,就像字符串后面加()
一样,无意义。
装饰函数就是利用了上述的返回内存地址这一特点产生的:
def decorat(f):
def inner(f):
return abs(f())
return inner
def add(x,y): 其中这三行等同于:@decorat
return x+y def add(x,y):
add = decorat(add) return x+y
上面的装饰器完成加完后取绝对值(写程序时有点迷装饰器卡了下看了篇文章他就是用这个例子,我借用下),装饰器的意义在于,不修改add这个函数,但却给add做了调整(装饰,给add加了些功能),关键点在于内层既执行了add(目标函数)又有其他的语句,然后又将内层函数的地址传给目标函数的“变量“,毕竟函数的名称是什么不重要,重要的是名称背后的地址。至于带参装饰函数更简单了,没有想象的那么好用或者说神奇,@XX这种形式的装饰明白的话,你就想,能不能在@XX后面加括号做手脚带个参数啥的,答案是可以,但带了参数就相当于执行函数了,即@和XX()是分开的东西,你的所要达到的效果是让XX()执行的结果等于函数装饰器的外层函数的内存地址,即XX()的返回值为第二层函数地址本身,明白这一点,则带参装饰器包括装饰器都明白了。
都两点了,赶紧睡觉,我太难了o(╥﹏╥)o

Python学习之高阶函数--嵌套函数、函数装饰器、含参函数装饰器的更多相关文章

  1. Python学习笔记 - 高阶函数

    高阶函数英文叫Higher-order function.什么是高阶函数?我们以实际代码为例子,一步一步深入概念. 变量可以指向函数 以Python内置的求绝对值的函数abs()为例,调用该函数用以下 ...

  2. python学习笔记——高阶函数map()

    满足以下两点中任意一点,即为高阶函数: 1.函数接收一个或多个函数作为参数 2.函数返回一个函数 1 描述 用函数和可迭代对象中每一个元素作为参数,计算出新的迭代对象 map() 会根据提供的函数对指 ...

  3. python学习之高阶函数

    filter函数:filter()为已知的序列的每个元素调用给定的布尔函数,调用中,返回值为非零的元素将被添加至一个列表中 list = filter(调用函数名,可迭代对象)——调用函数名自动传参— ...

  4. Python入门篇-高阶函数

    Python入门篇-高阶函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.高级函数  1>.First Class Object 函数在Python中是一等公民 函数也 ...

  5. Python 函数式编程 & Python中的高阶函数map reduce filter 和sorted

    1. 函数式编程 1)概念 函数式编程是一种编程模型,他将计算机运算看做是数学中函数的计算,并且避免了状态以及变量的概念.wiki 我们知道,对象是面向对象的第一型,那么函数式编程也是一样,函数是函数 ...

  6. Python中的高阶函数与匿名函数

    Python中的高阶函数与匿名函数 高阶函数 高阶函数就是把函数当做参数传递的一种函数.其与C#中的委托有点相似,个人认为. def add(x,y,f): return f( x)+ f( y) p ...

  7. python进阶学习之高阶函数

    高阶函数就是把函数当做参数传递的一种函数, 例如: 执行结果: 1.map()函数 map()接收一个函数 f 和一个list, 并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 l ...

  8. 匿名函数python内置高阶函数以及递归

    匿名函数 python定义一个函数通常使用def关键词,后面跟函数名,然后是注释.代码块等. def func(): '''注释''' print('from func') 这样就在全局命名空间定义了 ...

  9. 说说 Python 中的高阶函数

    高阶函数(higher-order function)指的是:接受一个函数为参数,或者把函数作为结果值返回的函数. 1 sorted() 比较常见的高阶函数是 sorted(),其内部的关键字参数 k ...

随机推荐

  1. Hibernate数据保存操作方法的原理对比

    Interface Session All Superinterfaces: Serializable All Known Subinterfaces: EventSource, Session Al ...

  2. 第十九篇:Mysql两次Group by和ip转数字作比较的一次优化

    业务场景:两张表,ipconfig_group表存了单位和 ip 起始段信息 visit_info表存储了访问次数,失败次数,访问流量,用户ip等信息 两张表的关系为:    一个部门下有若干ip段, ...

  3. MyBatis - Generator(MBG)

    前言 MyBatis Generator简称MBG,是一个专门为MyBatis框架使用者定制的代码生成器, 可以快速的根据数据表自动生成Bean对象.Java接口及SqlMapper.xml配置文件. ...

  4. 6_5.springboot2.x数据整合springData JPA

    1.配置文件 pom.xml <dependencies> <dependency> <groupId>org.springframework.boot</g ...

  5. 多重背包 /// 单调队列DP oj1943

    题目大意: em.... 就是多重背包 挑战340页的东西 ...自己的笔记总结总是比较乱的 重点:原始的状态转移方程中 更新第 i 种物品时 重量%w[i] 的值不同 则它们之间是相互独立的: 1- ...

  6. Entity Framework Code First 模式-建立一对一联系

    使用的例子为教室(ClassRoom),教室里的多媒体设备(Device),一个教室里有一套多媒体设备,一套多媒体设备只放在一个教室里. 1.Data Annotations方式 需要在任意一方的主键 ...

  7. BOM相关知识点

    1.BOM概念:Browser Object Model 浏览器对象模型作用:提供了使用JS操作浏览器的接口 2.BOM包含了许多对象信息,包括如下这些:(1)screen 屏幕信息(2)locati ...

  8. Math: Fibonacci

    https://www.zhihu.com/question/28062458 http://blog.csdn.net/hikean/article/details/9749391 对于Fibona ...

  9. 3.pycharm spark配置

        pycharm 内的环境变量配置     选择相应的spark程序文件的对应的配置信息       PYSPARK_PYTHON:python的安装路径   PYTHONPATH:spark安 ...

  10. LoadRunner如何调用外部函数

    LoadRunner如何调用外部函数 使用 VuGen 时,可以调用在外部 DLL 中定义的函数.通过从脚本调用外部函数,可以降低脚本的内存使用量以及总体运行时间.要调用外部函数,需要加载定义了该函数 ...