赞
踩
#普通函数定义与调用
def hi(name="nihao"):
return "hi" +name
print(hi())
"""hinihao"""
#我们可以将函数名赋给一个变量,传递的是引用
greet = hi
print(greet())
"""hinihao"""
#函数无返回值时输出None
def hi(name="nihao"):
print( "hi" +name)
print(hi())
a,接收单个参数
*args接收元组型参数
**kwargs接收字典型参数
def func(a,*args,**kwargs):
"""不管如何调用func()函数,第一个参数a是必需的,否则报错typeerror"""
print(a,end=">>")
print(args,end=">>")
print(kwargs)
func(3,4,5,6)
#输出结果:3>>(4, 5, 6)>>{}
func(3,text="你好")
#输出结果:3>>()>>{'text': '你好'}
func(text="你好")
#func() missing 1 required positional argument: 'a'
def hi(name="nihao"): """嵌套的函数""" print("你好,中国") def greet(): print("你好世界") def welcome(): print("欢迎来北京") print(greet()) #greet()函数无返回值,故print函数输出None print(welcome()) #无返回值,输出None print(hi()) #无返回值,输出None """ 你好,中国 你好世界 None 欢迎来北京 None None """ def hi(name="nihao"): print("你好,中国") def greet(): return "你好世界" def welcome(): return "欢迎来北京" print(greet()) print(welcome()) print(hi()) greet() #显示语法错误,并不能在嵌套函数外部访问到内部的函数 """ 你好,中国 你好世界 欢迎来北京 None """
#从函数中返回函数 def hi(name="zhang"): def greet(): return "now you are in greet func" def welcome(): return "now you are in welcome" if name == "zhang": return greet else: return welcome a = hi() #执行hi()函数,返回greet方法的引用 print(hi()) print(a) #返回的只是函数名greet,也就是说a指向了greet()函数的函数名所在地址,并不会发生函数调用 print(a()) #a()调用方法 """ <function hi.<locals>.greet at 0x0000028138E57B88> <function hi.<locals>.greet at 0x0000028138E57D38> now you are in greet func """
#将函数作为参数传递给另一个函数
def hi():
return "中国"
def hello(func):
print("正在做一些准备工作")
print(func())
hello(hi) #传递hi函数的引用
"""
正在做一些准备工作
中国
"""
#闭包:在一个外层函数中定义了一个内部函数,内部函数使用了外部函数的临时变量,并且外部函数的返回值是内部函数 """闭包: 1.嵌套 2.内部使用了外部变量 3.返回的是内部函数""" #第一个装饰器 def a_new_decorator(a_func): a = 10 def wrap_the_func(): print("a的值",a) print("在执行a_func()之前做一些工作") a_func() #闭包:内部函数引用了外部函数的参数a_func print("在执行a_func()之后做一些工作") return wrap_the_func #返回函数引用 """函数a_new_decorator()中有临时变量:a_func以及wrap_the_func;后者指向函数的地址""" def func1(): print("我是一个需要装饰器的函数") func1 = a_new_decorator(func1) #把函数wrap_the_func的引用传递给了func1 func1() """ a的值 10 在执行a_func()之前做一些工作 我是一个需要装饰器的函数 在执行a_func()之后做一些工作 """
#内部函数改变外部函数的参数的值,需要在内部函数中声明变量nonlocal def a_new_decorator(a_func): """nonlocal""" a = 10 def wrap_the_func(): nonlocal a a += 10 print("a的值",a) print("在执行a_func()之前做一些工作") a_func() print("在执行a_func()之后做一些工作") return wrap_the_func def func1(): print("我是一个需要装饰器的函数") func1 = a_new_decorator(func1) func1()
#可以看到,装饰器对函数进行封装,并且能修改被封装函数的行为 """开放(与那函数功能更加强大)、封闭(不能改变原函数)""" def a_new_decorator(a_func): #装饰器函数 print("-------->1") print("被装饰函数的地址",a_func) def wrap_the_func(): print("在执行a_func()之前做一些工作") #调用被装饰函数 a_func() print("在执行a_func()之后做一些工作") print("-------->2") return wrap_the_func @a_new_decorator #所以@a_new_decorator等同于func1 = a_new_decorator(func1) def func1(): #被装饰函数 print("我是一个需要装饰器的函数") print("-------->3") func1() print("-------->4") print(func1.__name__) #使用装饰器,把装饰函数的引用传递给被装饰器函数,在执行函数时自动调用装饰器函数而不能更改被装饰函数 #从输出来看,@a_new_decorator相当于进行了一次传参调用 """ -------->1 被装饰函数的地址 <function func1 at 0x000001BC7822ECA8> -------->2 -------->3 在执行a_func()之前做一些工作 我是一个需要装饰器的函数 在执行a_func()之后做一些工作 -------->4 wrap_the_func """
"""使用装饰器在进行支付之检查登录状态""" import time is_login = False def login_required(func): """被装饰函数含有参数,内部参数也应定义相应数量的参数""" def wrapper(goods): if is_login: #执行付款操作 func(goods) else: print("请先登录") login_status = login() if login_status: func(goods) else: print("用户名或密码错误") login() return wrapper @login_required def pay(goods): total_price = 0 if isinstance(goods,dict): print("所有商品列表如下") for grocery,price in goods.items(): print("商品%s价格%f" % (grocery,price)) total_price += price print("一共需支付%f" % total_price) print("付款中") time.sleep(2) def login(): username = input("请输入用户名") passwd = input("请输入密码") if username == "admin" and passwd == "1234": print("登录成功") is_login = True else: print("登陆失败") return is_login goods = {"三只松鼠":46.58,"蓝月亮":35,"Martin":5668} pay(goods)
def decorator(func): """装饰器装饰多个函数,接收不定参数使用形参*args,**kwargs""" def wrapper(*args): print("----->1") #func(args) #test1() missing 1 required positional argument: 'b' func(*args) print("----->2") return wrapper @decorator def test1(a,b,c=10): print("和为",a+b+c) @decorator def test2(): print("你好") test1(6,8) test2()
""" 定义装饰器一般格式: def decorator(func): def wrapper(*args,**kwargs): ... ... func(*args,**kwargs) ... return wrapper 返回值的通用性: def decorator(func): def wrapper(*args,**kwargs): ... ... return func(*args,**kwargs) return wrapper 或者: def decorator(func): def wrapper(*args,**kwargs): ... result = func(*args,**kwargs) return result return wrapper """ def decorator(func): def wrapper(*args,**kwargs): print("你好") result = func(*args,**kwargs) return result return wrapper @decorator def test(a,b): print(a+b) return "世界" f = test(2,3) print(f)
""" 装饰器带参数 """ def decorator(args1): def wrapper_outer(func): def wrapper(*args,**kwargs): print("---装饰前",args1) if args1 == "AA": func(*args,**kwargs) print("----->进入AA家") elif args1 == "BB": func(*args,**kwargs) print("----->进入BB家") else: func(*args,**kwargs) print("路由错误") print("---装饰后",args1) return wrapper return wrapper_outer @decorator("AA") def test1(): print("------>test1") def test(a): print("------>test",a) return 'hello' test1() """ ---装饰前 AA ------>test1 ---装饰后 AA """
""" 多层装饰器 装饰顺序按就被装饰函数近的原则进行装饰 装饰后的最外层装饰器的函数引用指向被装饰函数 """ def decorator(args1): def wrapper_outer(func): def wrapper_butterfly(*args,**kwargs): print("---装饰前",args1) func(*args,**kwargs) #func = wrapper_paper print("---装饰后",args1) return wrapper_butterfly return wrapper_outer def decorator2(args1): def wrapper_outer(func): def wrapper_paper(*args,**kwargs): print("---装饰前",args1) func(*args,**kwargs) print("---装饰后",args1) return wrapper_paper return wrapper_outer """根据就近原则,先运行装饰器@decorator("包装纸"),返回一个wrapper_paper引用给外层装饰器, 也就是说装饰器@decorator2("蝴蝶结")装饰的对象是wrapper_paper,最后返回wrapper_butterfly 的引用给test1""" @decorator2("蝴蝶结") @decorator("包装纸") def test1(): #test1 = wrapper_butterfly print("------>test1") test1() """ ---装饰前 蝴蝶结 ---装饰前 包装纸 ------>test1 ---装饰后 包装纸 ---装饰后 蝴蝶结 """
class DataSet(object):
@property
def method_with_property(self): ##含有@property
return 15
def method_without_property(self): ##不含@property
return 15
l = DataSet()
print(l.method_with_property) # 加了@property后,可以用调用属性的形式来调用方法,
#后面不需要加()
print(l.method_without_property()) #没有加@property , 必须使用正常的调用方法的形式,
#即在后面加()
class DataSet(object):
def __init__(self):
self._images = 1
self._labels = 2 #定义属性的名称
@property
def images(self): #方法加入@property后,这个方法相当于一个属性,这个属性可以让用户
#进行使用,而且用户没办法随意修改。
return self._images
@property
def labels(self):
return self._labels
l = DataSet()
#用户进行属性调用的时候,直接调用images即可,而不用知道属性名_images,因此用户无法更改属
#性,从而保护了类的属性。
print(l.images) # 加了@property后,可以用调用属性的形式来调用方法,后面不需要加()
""" 装饰器函数不带参数: def decorator(func): def wrapper(): ... ... func() ... return wrapper 装饰器函数带不变参数: def decorator(func): def wrapper(参数个数与被装饰函数保持一致): ... ... func() ... return wrapper 装饰器函数带可变参数的装饰器,可实现一个装饰器装饰多个函数: def decorator(func): def wrapper(*args,**kwargs): ... ... func(*args,**kwargs) ... return wrapper 装饰器函数带有返回值的通用性: def decorator(func): def wrapper(*args,**kwargs): ... ... return func(*args,**kwargs) return wrapper 或者对返回值进行加工: def decorator(func): def wrapper(*args,**kwargs): ... result = func(*args,**kwargs) return result return wrapper 装饰器的使用步骤: 1.定义装饰器 闭包 + 参数 2.使用 @装饰器名字 def 被装饰函数(): ... 3.函数调用:A() @装饰器的后台执行: 1.将被装饰函数作为参数传递给装饰器 2.执行装饰器 3.将装饰器的返回值赋给被装饰函数 开发时的使用: 1.登录验证 2.flask中的路由就是通过装饰器完成 3.日志文件 """
参考:https://zhuanlan.zhihu.com/p/64487092 python @property的介绍与使用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。