python 函数基础及装饰器
没有参数的函数及return操作
def test1():
print ("welcome") def test2():
print ("welcomt test2")
return def test3():
print("welcome test3")
return ,,,["test3","retest"] x = test1() #test1()表示执行,将执行结果(返回值)赋给变量x,会自动执行,并且由于test1 没有返回值(没有return操作),print的时候会打印none
y = test2() #test2()执行,有print,也有return,由于return一个返回值,所以将return的值赋给变量y
z = test3() print (x)
print (test1) ----test1没有执行,会打印test1的内存对象
print (y)
print (z) 打印结果:
welcome ----》x的打印结果
welcomt test2 ----》 y的打印结果
welcome test3 ----》 z的打印结果
None ----》x的打印结果
0 -----》y的打印结果
(, , , ['test3', 'retest']) ---》z的打印结果 总结:
只有当函数赋给一个变量时,返回值才能打印出来
当返回值为0时(没有return操作):返回none
当返回值为1时(return n):返回n
当返回值大于1时(return a,b,bv,d):返回元组(a,b,bv,d)
带参数的函数
#位置参数调用
def test1(x,y): ##这里的x,y称之为形参
print (x)
print (y) test1(,) ###这里的1,2称之为实参 注:形参和实参位置必须一一对应,##关键参数不能写在位置参数前面 ##关键字调用,与形参顺序无关
def test1(x,y):
print (x)
print (y) test1(y=,x=) 这里 y=1 将值传给y,x=2将值传给x
参数组(非固定参数)
#打印出一个元组(n个参数转换成元组)
def test1(*args): ##传多个位置参数(及单个字符串类的参数),在参数不固定的情况下
print (args) test1(,,,,) ##打印一个字典(n个参数转换成字典)
def test1(**kwargs): ###接收多个关键字参数(及 键=值 类似的参数)
print (kwargs) test1(name='aa',age=,sex="man") 注:参数组一定要放在后面
高阶函数和嵌套函数
高阶函数说明:
- A:函数名当作实参传递给另一个函数
- B:函数名可以作为返回值
示例一:将函数名作为实参,传递给另一个函数
打印结果:
示例二:将函数名作为返回值
def bar():
print ('in the bar')
return "xx"
def test1(func):
print (func)
return func #func为传递进来的函数名,作为返回值返回,return的结果一个内存对象 print (test1(bar)) ##打印bar的内存地址(test1(bar)即将bar的内存作为参数地址传给 test1,即func=bar,print (func)则打印的bar的内存地址,return也返回bar的内存地址)
x=test1(bar) #这里bar不能加括号’()’,加了括号相当于把bar的返回值(相当于执行了bar,返回值为xx)传过去了,而不是传了一个函数
print (x()) #相当于执行了bar函数
执行结果:
<function bar at 0x0000020090A57F28> #print(func) 的值
<function bar at 0x0000020090A57F28> #return func的值
<function bar at 0x0000020090A57F28> X = test1(bar)的值
in the bar #x()的值
xx
示例:
retrun func 返回func的内存地址,t()相当于执行func,返回func函数的执行结果
嵌套函数
def foo():
print ('in the foo')
def bar():
print ('in the bar')
bar() foo() 打印结果: in the foo
in the bar
装饰器
一、无参数装饰器
import time def timer(func):
def deco():
start_time = time.time()
func() #func()=test1()
stop_time = time.time()
print ("the func run time is %s" % (stop_time-start_time))
return deco ##返回deco的内存地址 @timer ### 等价于 test1=timer(test1),将test1函数的作为实参传给timer,所以test1=func,func()=test1()
def test1():
time.sleep(3)
print ("in the test1") print (timer(test1)) ##打印deco的内存地址#此时会打印deco的内存地址(因为,将test1函数传给timer,即func=test1,此时无论deco函数做啥操作,deco函数都没有执行,最后直接执行的是return deco,返回deco的内存地址) r = timer(test1) ##将deco的返回值(内存地址)赋给r,r() 则会执行deco这个函数(即deco())
r()
打印结果:
<function timer.<locals>.deco at 0x00000182EEAE9EA0>
in the test1
the func run time is 3.000403881072998
the func run time is 3.003307342529297
实例二
import time def timer(func):
def deco():
start_time = time.time()
func() ###这里即执行 test1函数(func=test1) stop_time = time.time()
print ("the func run time is %s" % (stop_time-start_time))
return deco @timer ### 等于 timer(test1),此时test1为一个内存对象
def test1():
time.sleep(3)
print ("in the test1") test1() 打印结果:
in the test1
the func run time is 3.0003435611724854
带参数的装饰器
带参数的装饰器即为在要被装饰的的函数里传入参数。例:
#所有参数可用*args,**kwargs代替 import time
def timer(func):
def deco(arg1):
start_time = time.time()
func(arg1) ###这里相当于执行test2(‘aaa’)
stop_time = time.time()
print ("the func run time is %s" % (stop_time-start_time))
return deco ##返回deco的内存地址 @timer
def test2(aa): ##相当于将test2函数作为实参传给timer,即test2=timer(test2),test2=func ,func声明了deco函数,但没有执行,此时返回了deco的内存地址(deco加上括号“()”即可执行,所以test2()=deco()),
#所以 test2()传入一个参数执行等于deco()传入一个参数执行,
time.sleep(2)
print ('in the test2 %s ' % aa)
#r1 = timer(test2)
#r1("bb") ##根据上面说明,r1的结果为deco的内存地址,r1()执行就等于 deco()执行
test2('aaa') ##test2(‘aaa’) 即等于 deco(‘aaa’),所以deco函数也要加上参数
打印结果
in the test2 aaa
the func run time is 2.0001180171966553
装饰器内部参数判断
#_*_coding:utf-8_*_ user_status = False #用户登录了就把这个改成True def login(auth_type): #把要执行的模块从这里传进来
def auth(func):
def inner(*args,**kwargs):#再定义一层函数
if auth_type == "qq":
_username = "alex" #模拟这是DB里存的用户信息
_password = "abc!23" #模拟这是DB里存的用户信息
global user_status if user_status == False:
username = input("user:")
password = input("pasword:") if username == _username and password == _password:
print("welcome login....")
user_status = True
else:
print("wrong username or password!") if user_status == True:
return func(*args,**kwargs) # 看这里看这里,只要验证通过了,就调用相应功能
else:
print("only support qq ")
return inner #用户调用login时,只会返回inner的内存地址,下次再调用时加上()才会执行inner函数 return auth def home():
print("---首页----") @login('qq')
def america():
#login() #执行前加上验证
print("----衣服专区----") def japan():
print("----化妆品专区----") @login('weibo')
def henan(style):
'''
:param style: 喜欢看什么类型的,就传进来
:return:
'''
#login() #执行前加上验证
print("----河南专区----") home()
# america = login(america) #你在这里相当于把america这个函数替换了
#henan = login(henan) # #那用户调用时依然写
america() # henan("3")
实例二
import time def timer(auth_type):
def warpper(func):
def deco(*args,**kwargs):
if auth_type == "local":
print ("welcome to local auth %s" % auth_type)
start_time = time.time()
func()
stop_time = time.time()
print ("the func run time is %s" % (stop_time-start_time))
else:
print ("ni da ye de %s" % auth_type)
return deco
return warpper @timer(auth_type="ldap") ### 等于 test1=timer(test1) 这里timer加上了括号并传了参数,会将auth_type的值传给timmer函数,然后会执行warpper(),
# 此时还没有调用(需要在最下面调用test1和test2的时候才会调用执行)
def test1():
time.sleep(3)
print ("in the test1") @timer(auth_type="local") ##这里的参数为作装饰器函数的参数
def test2():
print ("in the test2") test1()
test2() 打印结果:
ni da ye de ldap
welcome to local auth local
in the test2
the func run time is 0.0
双层装饰器
实例
user_info = {} def check_login(func): #### 检查是否的登陆
def inner(*args,**kwargs):
if user_info.get('is_login',None): ####字典的get方法
r = func(*args,**kwargs)
return r
else:
print ("please login")
return inner def check_admin(func): ####检查是否是admin权限
def inner(*args,**kwargs):
if user_info.get('user_type',None) == 2: ###2为管理员权限
r = func(*args,**kwargs)
return r
else:
print("perssion deined")
return inner @check_login ###双层装饰器
@check_admin ###双层装饰器
def index(): ###manage user login
print ('welcome') @check_login
def home(): ###普通用户登陆 def login():
c = input('user:')
if c == 'admin':
user_info['is_login'] = True
user_info['user_type'] = 2
else:
user_info['is_login'] = True
user_info['user_type'] = 1 def main():
while True:
a = input("1:denglu ,2:chakan xinxi ,3:super manager ")
if a == "":
login()
elif a == "":
home()
elif a == "":
index() main() 执行说明:
在双层装饰器 处,从上往下执行,即,先执行@check_login加载到内存,在执行@check_admin,加载到内存,然后执行index函数
解析顺序(从下往上):
将@check_admin 和index函数作为一个参数传到@check_login函数下,即 check_login(func)下的func参数为 check_admin 和index函数 这个整体,
然后顺序执行,如果check_login的条件满足了(满足已经登陆了),在执行check_admin函数(是否满足为admin用户),如果check_admin函数也满足了,则执行index函数(执行index)
python 函数基础及装饰器的更多相关文章
- python函数与方法装饰器
之前用python简单写了一下斐波那契数列的递归实现(如下),发现运行速度很慢. def fib_direct(n): assert n > 0, 'invalid n' if n < 3 ...
- Python函数篇:装饰器
装饰器本质上是一个函数,该函数用来处理其他函数,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理. ...
- 函数基础(三) 装饰器\闭包 day 12
目录 昨日回顾 可变长参数 * ** 函数对象 函数嵌套 名称空间和作用域 今日内容 闭包函数 装饰器 语法糖 装饰器模板 迭代器 昨日回顾 可变长参数 * *形参:接受多余的位置实参 *实参(可迭代 ...
- python函数学习之装饰器
装饰器 装饰器的本质是一个python函数,它的作用是在不对原函数做任何修改的同时,给函数添加一定的功能.装饰器的返回值也是一个函数对象. 分类: 1.不带参数的装饰器函数: def wrapper( ...
- python函数:叠加装饰器、迭代器、自定义迭代器、生成式
一.叠加多个装饰器二.迭代器三.自定义迭代器四.xxx生成式 一.叠加多个装饰器 # 加载装饰器就是将原函数名偷梁换柱成了装饰器最内层那个wrapper函数 # 在加载完毕后,调用原函数其实就是在调用 ...
- python基础之 装饰器,内置函数
1.闭包回顾 在学习装饰器之前,可以先复习一下什么是闭包? 在嵌套函数内部的函数可以使用外部变量(非全局变量)叫做闭包! def wrapper(): money =10 def inner(num) ...
- Day11 Python基础之装饰器(高级函数)(九)
在python中,装饰器.生成器和迭代器是特别重要的高级函数 https://www.cnblogs.com/yuanchenqi/articles/5830025.html 装饰器 1.如果说装 ...
- python基础(8)-装饰器函数&进阶
从小例子进入装饰器 统计一个函数执行耗时 原始版本 import time # time模块有提供时间相关函数 def do_something(): print("do_something ...
- python基础之函数当中的装饰器
在实际工作当中存在一个开放封闭原则 1.对扩展是开放的 为什么要对扩展开放呢? 我们说,任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改.所以我们必须允许代码扩展.添加新 ...
随机推荐
- Django models中关于blank与null的补充说明
Django models中关于blank与null的补充说明 建立一个简易Model class Person(models.Model): GENDER_CHOICES=( (1,'Male'), ...
- eclipse中无法查看引用的jar包源码
本文来源:http://blog.csdn.NET/zljjava/article/details/7545270(这篇博客也是转载的,向最原始的作者致敬) 1.下载JAD jad官方地址的官方下载地 ...
- mysql操作命令
一.MySQL连接命令 mysql-u:指定用户-p:指定密码-S:指定socket文件-P:指定端口-h:指定主机域-e:指定sql语句 mysql> status \s 查看状态 mysql ...
- 洛谷P2918 [USACO08NOV]买干草(一道完全背包模板题)
题目链接 很明显的一道完全背包板子题,做法也很简单,就是要注意 这里你可以买比所需多的干草,只要达到数量就行了 状态转移方程:dp[j]=min(dp[j],dp[j-m[i]]+c[i]) 代码如下 ...
- Goldbach's Conjecture POJ - 2262 线性欧拉筛水题 哥德巴赫猜想
题意 哥德巴赫猜想:任一大于2的数都可以分为两个质数之和 给一个n 分成两个质数之和 线行筛打表即可 可以拿一个数组当桶标记一下a[i] i这个数是不是素数 在线性筛后面加个装桶循环即可 #inc ...
- SHELL编程综合练习
SHELL编程综合练习1 一. 实验准备(预防抄袭,此步必做) 请将命令提示符设为你的学号:输入PS1=你的学号_,即学号之后跟下划线,例如PS1=110015_, 回车执行 如发现命令提示符和你的学 ...
- 【XSY2772】数列 特征多项式 数学
题目描述 给你一个数列: \[ f_n=\begin{cases} a^n&1\leq n\leq k\\ \sum_{i=1}^k(a-1)f_{n-i}&n>k \end{c ...
- Linux block(1k) block(4k) 换算 gb
输入 df 显示1k blocks 大小 再输入 df -h 显示 gb换算大小 结论 block(1k) 计算公式为: block(1k) /1024/1000 = xx gb ...
- expect 自动化控制命令
expect 的核心是 spawn expect send set spawn 调用要执行的命令expect 等待命令提示信息的出现,也就是捕捉用户输入的提示:send 发送需要交互的值,替代了用户手 ...
- android TextView字体设置最少占多少行. 及其 Java String 字符串操作 . .
① 字体设置: 修改代码 : GridViewActivity.java priceTv为 TextView priceTv.setMaxLines(3); //当多与7个字fu的时候 , 其余字 ...