网络编程
位置:首页>> 网络编程>> Python编程>> python中*args与**kwarsg及闭包和装饰器的用法

python中*args与**kwarsg及闭包和装饰器的用法

作者:zew1040994588  发布时间:2023-07-24 00:43:34 

标签:python,args,kwarsg,闭包,装饰器

*args与**kwarsg及闭包和装饰器

过程

先理解闭包,再理解装饰器,不要忘了不定长参数

def func():
   msg = '111'
   def func1():
       print(msg)
   return func1

"""
1-理解闭包
闭包即内部函数调用外部函数作用域里面的变量
比如func1就是一个闭包函数
"""
func()()# 这里实际上是func1()
"""
2-装饰器
fn是被装饰的目标函数
2.1-仅仅只是传递函数名的装饰器[基本不会用到]
2.2-装饰带有参数的函数
2.3-装饰带有返回值的函数
2.4-装饰参数不确定的函数[可归类到装饰带有参数的函数里面]
2.5-装饰器本身携带参数
"""
def decorator(fn):
   def wrapper():
       print("添加的功能,装饰不带有参数的函数")
       return fn()
   return wrapper

@decorator
def test():
   print("原有功能")

test()# 实际上是decorator(test)

def decorator1(fn):
   def wrapper(n1,n2):
       print("添加的功能,装饰带有参数的函数")
       return fn(n1,n2)
   return wrapper

@decorator1
def test1(a,b):
   print("a+b=%s"%(a+b))
   print("原有功能")

test1(1,2)# 实际上是decorator1(test1(1,2))

def decoretor2(fn):
   def wrapper():
       print("添加的功能,装饰带有返回值的函数")
       res = fn()
       return res
   return wrapper

@decoretor2
def test2():
   print("原有功能")
   return "返回值001"

a = test2() # 实际是decorator2(test2)
print(a)

def decorator3(fn):
   def warpper(*args,**kwargs):
       print("添加的功能,装饰不定长参数的函数")
       return fn(*args,**kwargs)
   return warpper

@decorator3
def test3(n1,n2,n3):
   print("原有功能")
   print(n1+n2+n3)

test3(1,2,3)# 实际上是decorator1(test1(1,2,3))

def decorator4(home):
   def func_1(fn):
       def wrapper(*args,**kwargs):
           print("装饰器本身携带参数")
           print("目前家在%s"%(home))
           return fn(*args,**kwargs)
       return wrapper
   return func_1

@decorator4(home='wuhan')
def test4(n1,n2,n3):
   print("原有功能")
   print(n1+n2+n3)

# test3(1,2,3)=decorator3(home="武汉")(test(1,2,3))()
"""
1-先调用decorator3(home="wuhan")
2-执行func_1(test(1,2,3)) # 到这里其实就和前面的装饰器一样
3-执行wrapper
4-执行test(1,2,3)
"""
test4(1,2,3)

python中*args与**kwarsg及闭包和装饰器的用法

Python fun(*args,**kwargs)中*args,**kwargs参数含义及用法

1. Python函数中的两种参数

我们知道,在Python中有两种参数

  • 位置参数(positional argument): 位置参数只能由参数位置决定

  • 关键词参数(keyword argument): 关键词参数只需要用 keyword = somekey 的方法即可传参

位置参数只能由参数位置决定。这也就决定了位置参数一定要在前面,否则关键词参数数量的变化都会使得位置无法判断。

2. 理解函数调用中的*

*的作用是将tuple或者list中的元素进行unpack,分开传入,作为多个参数。

def func(a,b,c)
    print(a,b,c)
alist = [1,2,3] # 这里alist的长度必须和函数中参数的个数相同,否则会报错
func(*alist)     # 等同于 func(1, 2, 3)
1 2 3

2.1 * 做了什么

它拆开数列alist的数值作为位置参数,并把这些位置参数传给函数func来调用。

因此拆数列、传位置参数意味着func(*alist)与func(1,2,3)是等效的,因为 alist= [1,2,3]。

3. 理解函数调用中的**

**的作用是unpack字典,并将字典中的数据项作为键值参数传给函数。

为了更好的理解举几个例子:

def func(a, b, c):
    print(a, b, c)
    
if __name__ == "__main__":
    dic = {'b': 2, 'c': 3}
    func(1, b=2, c=3)
    func(1, **dic)
1 2 3
1 2 3

4. 理解函数调用中的*args和**kwargs

kwargs是keyword argument的缩写,args就是argument。常见的是*args 在 **kwargs 前面。

这两个的用途和效果如下:

def this_fun(a,b,*args,**kwargs):
    """
    在这个函数定义中,参数”a, b”代表”常规参数列表”。
    args 接收元组作为位置参数,而非是常见的参数列表
    
    """
    print(a,b)
    print(args)
    print(kwargs)
if __name__ = '__main__'
    this_fun(0,1,2,3,index1=11,index2=22)
    
0,1
(2, 3)
{'index2': 22, 'index1': 11}

也就是说,第一中不定的参数形式把剩下的没有关键字的参数收起来形成一个tuple,而第二种把有关键字的收起来做成一个字典。

5. 实例说明args, kwargs的应用场景

5.1 子类传参给父类方法

在任何时候继承类和重写方法的,我们应当用到args, kwargs将接收到的位置参数和键值参数给父类方法。通过实例我们更好的理解

class Model(object):
    def __init__(self, name):
        self.name = name
    def save(self, force_update=False, force_insert=False):
        if force_update and force_insert:
            raise ValueError("Cannot perform both operations")
        if force_update:
            print("Updated an existing record")
        if force_insert:
            print("Created a new record")

定义一个类,我们可以创建类的对象,类的对象有一个方法save().假设类的对象可以通过save()方法保存到数据库中。通过函数save()参数来决定是否在数据库中创建一条记录或者更新现存的记录。

构造一个新类,类有Model的行为,但只有符合某些条件才会保存这个类的对象。这个新类继承Model,重写Model的save()

class ChildModel(Model):
    def save(self, *args, **kwargs):
        if self.name == 'abcd':
            super(ChildModel, self).save(*args, **kwargs)
        else:
            return None

实际上对应的保存动作发生在’Model’的save方法中。所以我们调用子类的的save()方法而非’Model’的方法.子类ChildModel的save()接收任何父类save()需要的参数,并传给父类方法。因此,子类save()方法参数列表中有*args和**kwargs,它们可以接收任意位置参数或键值参数,常规参数列表除外。

下面创建ChildModel实体并调用save方法:

c=ChildModel('abcd')
c.save(force_insert=True)
c.save(force_update=True)
# 结果
Created a new record
Updated an existing record

这里传参数给对象的save()方法。调用的是子类的save(), 它接收一个包含关键字参数kwargs的字典。然后,它使用**将字典作为关键字参数unpack,然后将其传递给超类save()。因此,超类save()获得关键字参数force_insert并执行相应的操作。

5.2 *args 实现sum

def my_sum(*args):
    res = 0
    for val in args:
        res += val
    return res
    
l1 = [4, 8]
l2 = [1,2,3]
print(my_sum(*l1))         # 12
print(my_sum(*l2))         # 6
print(my_sum(4,5,6))     # 15

来源:https://blog.csdn.net/Elephantpretty/article/details/124066408

0
投稿

猜你喜欢

  • CSS布局中可以用javascript判断浏览器版本看如下的javascript脚本: if (window.XMLHt
  • 随着PHP4.0和JSP技术的推出以及IIS中不断出现的重大的安全问题,MicroSoft的ASP的市场仿佛是变的狭窄了,但是 MicroS
  • ASP(Active Server Page)是Microsoft公司推出的基于PWS(Personal We
  •  在ASP.net页面中,我们编写JavaScript脚本附加有注释时,这些注释也往往会随JavaScript脚本一起送到客户端。
  • MaxDB和MySQL是独立的数据库管理服务器。系统间的协同性是可能的,通过相应的方式,系统能够彼此交换数据。要想在MaxDB和MySQL之
  • 我就废话不多说了,大家还是直接看代码吧~#aaa.py#version 3.5import os #这句是没用了,不知道为什么markdow
  • 基本上快被这个问题搞疯了,症状如下症状描述:在ie下(6或7,8没有试过)当出现中英文混排,都采用默认字体时,并使用 li 列表做float
  • 包括安装时提示有挂起的操作、收缩数据库、压缩数据库、转移数据库给新用户以已存在用户权限、检查备份集、修复数据库等。 (一)挂起操作在安装S
  • 1、动态sql, 即动态参数:在存储过程中,想要直接用表名变量做参数,动态执行sql,不能直接写<P>create proced
  • 其主要的优点便是无需再手工添加大量的信息了,可以指定对某一个站信息的截取进行批量录入,达到省时省力的目的。与其单纯的ASP小偷程序不同的是:
  • 设置cookie每个cookie都是一个名/值对,可以把下面这样一个字符串赋值给document.cookie:document.cooki
  • 不同于其他软件项目,互联网项目的开发有其独有的特性。互联网项目开发不同于传统软件项目开发不同于需求定制性的软件开发公司。客户的需求是明确的,
  • 问题你想在使用范围内执行某个代码片段,并且希望在执行后所有的结果都不可见。解决方案为了理解这个问题,先试试一个简单场景。首先,在全局命名空间
  • MySQL目前不支持列的Default 为函数的形式,如达到你某列的默认值为当前更新日期与时间的功能,你可以使用TIMESTAMP列类型下面
  • SQL Server的以前版本在跟踪对象相关性方面做的并不好。原因是所有的对象相关性都是由对象ID来跟踪的,这意味着对象一开始就必须存在。但
  • CacheControl 属性设置是否可缓存由 ASP 生成的输出。默认地,代理服务器不会保持缓存副本。语法:response.CacheC
  • 通常我们会在一些javascript的书籍上看到,使用Javascript保留字作为标识符(变量名、函数名、循环标记等)时,会引起程序报错!
  • eWebEditor在线HTML编辑助手是基于eWebEditor在线HTML编辑器的扩展工具。当您的电脑安装了eWebEditor在线HT
  • 前后端分离前后端分离的好处最大的好处就是前端JS可以做很大部分的数据处理工作,对服务器的压力减小到最小。后台错误不会直接反映到前台,错误接秒
  • 一、什么是匿名函数?在Javascript定义一个函数一般有如下三种方式:函数关键字(function)语句:function f
手机版 网络编程 asp之家 www.aspxhome.com