zoukankan      html  css  js  c++  java
  • python 之 functools模块

    functools模块用于高阶函数:作用于或返回其他函数的函数。一般而言,任何可调用对象都可以作为本模块用途的函数来处理。

    官方文档已经有了详尽的介绍,这里就不在复述,详情请见:官方文档 。这里主要介绍下 partial。

    partial 详解

    functools.partial返回的是一个可调用的partial对象,使用方法是partial(func,*args,**kw),func是必须要传入的,而且至少需要一个args或是kw参数。

    from functools import partial
    def add(a, b, c):
        return a+b+c
    
    p = partial(add, 12)
    p(1, 2)
    # 15
    p(2, 3)
    17
    p(3, 4)
    # 19
    

      创建一个功能函数,实现三个数的相加,如果其中的一个或是多个参数不变,那么可以使用partial,实例化一个传入了add和12参数的对象,如上图所示,传入两个参数后,得到三个数的和。

    partial源码分析:

        1.__new__方法部分

        class partial:
            """New function with partial application of the given arguments
            and keywords.
            """
            ###__SLOTS__ 只允许类有此属性,不能动态的添加其他的属性
            __slots__ = "func", "args", "keywords", "__dict__", "__weakref__"     
            ###__new__方法生成实例对象
            def __new__(*args, **keywords):
            ###实例化对象时传入参数的限定,不能为空、参数的个数要大于等于2,这就解释了至少需要一个或多个args或是kw,func是一个可调用的对象,是必须要传入的
                if not args:
                    raise TypeError("descriptor '__new__' of partial needs an argument")
                if len(args) < 2:
                    raise TypeError("type 'partial' takes at least one argument")
                cls, func, *args = args # args=(cls,func,*args)
                if not callable(func):
                    raise TypeError("the first argument must be callable")
                ### 位置参数是以元组的形式传入的    
                args = tuple(args)
    
        ###hasattr这块我也没有咋个明白,不知道可以应用到什么地方,从使用方法来看,传入的函数func要有属性或是方法,如果知道请告知我一下
            if hasattr(func, "func"):
                args = func.args + args
                tmpkw = func.keywords.copy()
                tmpkw.update(keywords)
                keywords = tmpkw
                del tmpkw
                func = func.func    
        ###创建一个实例对象本身
            self = super(partial, cls).__new__(cls)
        ###动态的添加属性
            self.func = func
            self.args = args
            self.keywords = keywords
            return self
    

     上面的代码创建了一个实例对象(p=partial(func,*args,**kw)),并给对象本身添加了属性。

        2. __call__方法部分

    再看可调用的部分,partial实例化的对象是一个可调用的,是因为在partial中写了__call__方法,看源码:

    ###在使用p()时会自动调用__call__方法	
    def __call__(*args, **keywords):
        if not args:
            raise TypeError("descriptor '__call__' of partial needs an argument")
        self, *args = args
    ###将位置参数和关键字参数分别合在一起,在使用p()的时候只传入了部分的参数,这是为了我们的方便,不重复传入不变的参数,而在__call__方法中会将func所需的参数全部传入	
        newkeywords = self.keywords.copy()
        newkeywords.update(keywords)
    ###*self.args是partial(func,*args,**kw)中的*args
        return self.func(*self.args, *args, **newkeywords)
    

     在使用p(*args,**keywords)的时候,就会自动的调用__call__方法,这就是生成的对象可调用的原因,self是实例化对象本身,*args、**kw是我们传入函数func的参数,但是只是传入了部分参数,这也是partial的作用所在,所以还要将partial(func,*args,**kw)中的位置参数和关键字参数与p(*args,**keywords)一并传入到函数func中来实现函数的功能。官网中解释partial的功能实现相当于:

    def partial(func, *args, **keywords):
        def newfunc(*fargs, **fkeywords):
            newkeywords = keywords.copy()
            newkeywords.update(fkeywords)
            return func(*args, *fargs, **newkeywords)
        newfunc.func = func
        newfunc.args = args
        newfunc.keywords = keywords
        return newfunc
    

     当调用partial函数的时候,返回的是newfunc函数对象,让f=partial(add,12),相当了f=newfunc,所以f是一个可调用的对象,因此f(1,2)-->等价于newfunc(1,2)-->将参数整合传入到func中,并返回func实现其功能。

    转自:https://blog.csdn.net/Zjack_understands/article/details/80242946

  • 相关阅读:
    Saltstack module gem 详解
    Saltstack module freezer 详解
    Saltstack module firewalld 详解
    Saltstack module file 详解
    Saltstack module event 详解
    Saltstack module etcd 详解
    Saltstack module environ 详解
    Saltstack module drbd 详解
    Saltstack module dnsutil 详解
    获取主页_剥离百度
  • 原文地址:https://www.cnblogs.com/zh605929205/p/9940274.html
Copyright © 2011-2022 走看看