Python学习之高阶函数--嵌套函数、函数装饰器、含参函数装饰器
玩了一晚上王者,突然觉得该学习,然后大晚上的搞出来这道练习题,凌晨一点写博客(之所以这么晚就赶忙写是因为怕第二天看自己程序都忘了咋写的了),我太难了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学习之高阶函数--嵌套函数、函数装饰器、含参函数装饰器的更多相关文章
- Python学习笔记 - 高阶函数
高阶函数英文叫Higher-order function.什么是高阶函数?我们以实际代码为例子,一步一步深入概念. 变量可以指向函数 以Python内置的求绝对值的函数abs()为例,调用该函数用以下 ...
- python学习笔记——高阶函数map()
满足以下两点中任意一点,即为高阶函数: 1.函数接收一个或多个函数作为参数 2.函数返回一个函数 1 描述 用函数和可迭代对象中每一个元素作为参数,计算出新的迭代对象 map() 会根据提供的函数对指 ...
- python学习之高阶函数
filter函数:filter()为已知的序列的每个元素调用给定的布尔函数,调用中,返回值为非零的元素将被添加至一个列表中 list = filter(调用函数名,可迭代对象)——调用函数名自动传参— ...
- Python入门篇-高阶函数
Python入门篇-高阶函数 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.高级函数 1>.First Class Object 函数在Python中是一等公民 函数也 ...
- Python 函数式编程 & Python中的高阶函数map reduce filter 和sorted
1. 函数式编程 1)概念 函数式编程是一种编程模型,他将计算机运算看做是数学中函数的计算,并且避免了状态以及变量的概念.wiki 我们知道,对象是面向对象的第一型,那么函数式编程也是一样,函数是函数 ...
- Python中的高阶函数与匿名函数
Python中的高阶函数与匿名函数 高阶函数 高阶函数就是把函数当做参数传递的一种函数.其与C#中的委托有点相似,个人认为. def add(x,y,f): return f( x)+ f( y) p ...
- python进阶学习之高阶函数
高阶函数就是把函数当做参数传递的一种函数, 例如: 执行结果: 1.map()函数 map()接收一个函数 f 和一个list, 并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 l ...
- 匿名函数python内置高阶函数以及递归
匿名函数 python定义一个函数通常使用def关键词,后面跟函数名,然后是注释.代码块等. def func(): '''注释''' print('from func') 这样就在全局命名空间定义了 ...
- 说说 Python 中的高阶函数
高阶函数(higher-order function)指的是:接受一个函数为参数,或者把函数作为结果值返回的函数. 1 sorted() 比较常见的高阶函数是 sorted(),其内部的关键字参数 k ...
随机推荐
- 如何查找一个命令由哪个rpm安装&&rpm 的相关查询方法
[root@test-can-nginx src]# which python3 /usr/bin/python3 [root@test-can-nginx src]# rpm -qf /usr/bi ...
- 第一篇:spring+springMVC项目启动最终笔记(一web.xml)
1.web应用启动从web.xml开始,首先创建一个全局的上下文(Context),名字叫ServletContext,可以理解为一间图书馆,或一个数据结构(如map,但是比map牛多了),整个结构类 ...
- 使用Python实现不同目录下文件的拷贝
目标:要实现将一台计算机的共享文件夹中的文件备份到另一台计算机,如果存在同名的文件只要文件的大小和最后修改时间一致,则不拷贝该文件 python版本:Python3.7.1 python脚本: fro ...
- 小程序开发之wepy框架
ps 本教程使用wepy 1.7+以上的版本 wepy-让小程序支持组件化开发的框架 鹅厂出品,用于开发自家产品的框架还是很良心的,框架设计思路上参照vue,但不是全部照搬,这点要注意. 对微信小程序 ...
- [转]Hessian——轻量级远程调用方案
Hessian是caucho公司开发的一种基于二进制RPC协议(Remote Procedure Call protocol)的轻量级远程调用框架.具有多种语言的实现,但用的最多的当然是Java实现 ...
- vim的个性化配置(方便编程)
在用户主目录下新建vimrc即可.例如: vim ~/.vimrc 然后复制进去即可. 配置如下: "关闭vim一致性原则 set nocompatible "显示行号 set ...
- 威胁预警|首现新型RDPMiner挖矿蠕虫 受害主机易被添加恶意账户
近日,阿里云安全发现一种新型挖矿蠕虫RDPMiner,通过爆破Windows Server 3389端口RDP服务的方式进行挖矿木马传播,致使用户CPU占用率暴涨,机器卡顿,更被创建名为Default ...
- 0818NOIP模拟测试赛后总结
又挂了…… 120 rank19. 第一次两个机房考不同的题目.一开始并不知道应该做哪套题目. 不明真相的吃瓜群众决定先点开B套.通读三道题,只是觉得T2好水.似乎是红题难度吧……(后来证明是我读错题 ...
- LUOGU P2476 [SCOI2008]着色方案
传送门 解题思路 毒瘤题,,刚开始写了个奇奇怪怪的哈希,结果T了5个点..后来深(kan)入(le)思(ti)考(jie),发现c的范围很小,设$f[a][b][c][d][e][pre]$表示还能 ...
- SpringBoot_02_SpringBoot的配置文件
1.SpringBoot配置文件 SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者appli ...