Python 进阶----*args和 **kwargs,装饰器 的用法

来源:互联网 发布:db2分页查询sql 编辑:程序博客网 时间:2024/06/07 18:21
# args 的用法def test_var_args(f_arg,*argv):print("first normal arg:",f_arg)for arg in argv:print("another arg through *argv:",arg)test_var_args('arg1','arg2','arg3')#first normal arg: arg1#another arg through *argv: arg2#another arg through *argv: arg3#**kwargs 的用法def test_var_kwarg(**kwargs):for key,value in kwargs.items():print("{keys} == {values}".format(keys=key,values=value))test_var_kwarg(name='yzf')#*args和**keargs的用法def test_args_kwargs(arg1, arg2, arg3):    print("arg1:", arg1)    print("arg2:", arg2)    print("arg3:", arg3)test_args = ("two", 3, 5)test_args_kwargs(*test_args)kwargs = {"arg3": 3, "arg2": "two", "arg1": 5}test_args_kwargs(**kwargs)


装饰器

#再谈装饰器def  simpleDecorator(b_func):def wrapBFuction():print("i am A,before B")b_func()print("i am C,follow B")return wrapBFuctiondef bFunction():print("i am B")b=simpleDecorator(bFunction)b()print(b.__name__)"""输出应该是“a_function_requiring_decoration”。这里的函数被warpTheFunction替代了。它重写了我们函数的名字和注释文档(docstring)。幸运的是Python提供给我们一个简单的函数来解决这个问题,那就是functools.wraps。我们修改上一个例子来使用functools.wraps:"""from functools import wrapsdef  simpleDecorator(b_func):@wraps(b_func)def wrapBFuction():print("i am A,before B")b_func()print("i am C,follow B")return wrapBFuction@simpleDecoratordef bDecorator():print("i am B,a simpleDecorator")bDecorator()print(bDecorator.__name__)#注意:@wraps接受一个函数来进行装饰,并加入了复制函数名称、注释文档、参数列表等等的功能。#这可以让我们在装饰器里面访问在装饰之前的函数的属性。"""#使用场景#1.授权:Authorization  装饰器能有助于检查某个人是否被授权去使用一个web应用的端点(endpoint)。它们被大量使用于Flask和Django web框架中.from functools import wrapsdef requires_auth(f):@wraps(f)def decorated(*args,**kwargs):auth = request.authorizationif not auth or not check_auth(auth.username, auth.password):authenticate()return f(*agrs,**kwargs)return decorated#2.日志(Logging)日志是装饰器运用的另一个亮点"""from functools import wrapsdef logit(func):@wraps(func)def with_log(*args,**kwargs):print(func.__name__+"was call")return func(*args,**kwargs)return with_log@logitdef add_function(x):print( "caculate x+x: ")return x+xresult = add_function(2)print(result)"""add_functionwas callcaculate x+x:4""""""带参数的装饰器,Python里每个东西都是一个对象"""from functools import wrapsdef logit_fun(logfile='out.log'):def logging_dacorator(func):@wraps(func)def wrap_log(*args,**kwargs):log_string=func.__name__+"was called"print(log_string)with open(logfile,'a') as file:file.write(log_string)return func(*args,**kwargs)return wrap_logreturn logging_dacorator@logit_fun()def noargs():pass@logit_fun(logfile='out2.log')def hasargs():passnoargs()hasargs()#装饰器类class Logit(object):def __init__(self,logfile='out.log'):self.logfile =logfiledef __call__(self,func):@wraps(func)def wrapped_func(*args,**kwargs):log_string = func.__name__ + "was call "print(log_string)with open(self.logfile,'a') as open_file:open_file.write(log_string + '\n')return func(*args,**kwargs)return wrapped_funcdef notify(self):pass@Logit(logfile = 'out3.log')def myfunc1():    passmyfunc1()class EmailLogit(Logit):"""docstring for EmailLogit"""def __init__(self, email = '1508287079@qq.com',*args,**kwargs):super(EmailLogit, self).__init__(*args,**kwargs)self.email= emaildef notify(self):# 发送一封email到self.email# 这里就不做实现了with open(self.logfile,'a') as open_file:open_file.write(self.email + '\n')print("send_email success!")pass#从现在起,@email_logit将会和@logit产生同样的效果,但是在打日志的基础上,还会多发送一封邮件给管理员@EmailLogit(logfile = 'out4.log')def send_email():EmailLogit().notify()send_email()