python高阶函数functools模块的具体使用

 更新时间:2023年03月27日 09:10:26   作者:alwaysrun  
本文主要介绍了python高阶函数functools模块的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

functools模块提供了一些常用的高阶函数(处理其他可调用对象/函数的特殊函数;以函数作为输入参数,返回也是函数)。

functools模块

functools模块中的高阶函数可基于已有函数定义新的函数:

  • cmp_to_key,
  • total_ordering,
  • reduce,
  • partial,
  • update_wrapper
  • wraps

reduce

reduce(function, iterable[, initializer])对一个可迭代数据集合中的所有数据进行累积。

  • function:接受两个参数的函数;
  • sequence:可迭代对象(tuple/list/dict/str);
  • initial:可选初始值;
# 累加
reduce(lambda x,y:x+y, [1,2,3,4]) # 10

# 逆序字符串
reduce(lambda x,y:y+x, 'abcdefg') # 'gfedcba'

partial/partialmethod

partial用于"冻结"函数的部分参数,返回一个参数更少、使用更简单的函数对象。使用时,只需传入未冻结的参数即可。partialmethod用于处理类方法。

functools.partial(func[, *args][, **keywords])返回一个新的partial对象:

  • func:一个可调用的对象或函数;
  • args:要冻结的位置参数;
  • keywords:要冻结的关键字参数。
def add(a, b, note="add"):
    result = a + b
    print(f"{note} result: {result}")
    return result

add3 = functools.partial(add, 3)
add5 = functools.partial(add, 5, note="partialed")

print(add3(1)) # add result: 4
print(add3(2, note="partial3")) # partial3 result: 5
print(add5(3)) # partialed result: 8

partialmethod用于类中的方法

class Cell(object):
    def __init__(self):
        self._alive = False

    @property
    def alive(self):
        return self._alive

    def set_state(self, state):
        self._alive = bool(state)

    set_alive = functools.partialmethod(set_state, True)
    set_dead = functools.partialmethod(set_state, False)

c = Cell()
print(c.alive)  # False

c.set_alive()
print(c.alive)  # True

wraps/update_wrapper

functools.update_wrapper(wrapper, wrapped [, assigned] [, updated])更新一个包裹(wrapper)函数,使其看起来更像被包裹(wrapped)的函数(即把 被封装函数的__name__、__module__、__doc__和 __dict__都复制到封装函数去。wraps是通过partial与update_wrapper实现的。

通常,经由被装饰(decorator)的函数会表现为另外一个函数了(函数名、说明等都变为了装饰器的);通过wraps函数可以消除装饰器的这些副作用。

def wrapper_decorator(func):
    @functools.wraps(func) # 若是去掉此wraps,则被装饰的函数名称与说明都变为此函数的
    def wrapper(*args, **kwargs):
        """doc of decorator"""
        print('in wrapper_decorator...')
        return func(*args, **kwargs)

    return wrapper

@wrapper_decorator
def example():
    """doc of example"""
    print('in example function')

example()
# in wrapper_decorator...
# in example function
print(example.__name__, "; ", example.__doc__) # example ;  doc of example

singledispatch/singledispatchmethod

singledispatch将普通函数转换为泛型函数,而singledispatchmethod(3.8引入)将类方法转换为泛型函数:

  • 泛型函数:是指由多个函数(针对不同类型的实现)组成的函数,调用时由分派算法决定使用哪个实现;
  • Single dispatch:一种泛型函数分派形式,基于第一个参数的类型来决定;

dispatch使用:

  • singledispatch装饰dispatch的基函数base_fun(即,注册object类型);
  • 注册后续分发函数使用装饰器@{base_fun}.register({type}),注册每种需要特殊处理的类型;
  • 分发函数名称无关紧要,_是个不错的选择;
  • 可以叠放多个register装饰器,让同一个函数支持多种类型;
# 缺省匹配类型,注册object类型(与后续注册类型都不匹配时使用)
@functools.singledispatch
def show_dispatch(obj):
    print(obj, type(obj), "dispatcher")

# 匹配str字符串
@show_dispatch.register(str)
def _(text):
    print(text, type(text), "str")

# 匹配int
@show_dispatch.register(int)
def _(n):
    print(n, type(n), "int")

# 匹配元祖或者字典
@show_dispatch.register(tuple)
@show_dispatch.register(dict)
def _(tup_dic):
    print(tup_dic, type(tup_dic), "tuple/dict")

### 打印注册的类型:
# dict_keys([<class 'object'>, <class 'str'>, <class 'int'>, <class 'dict'>, <class 'tuple'>])
print(show_dispatch.registry.keys())

show_dispatch(1)
show_dispatch("xx")
show_dispatch([1])
show_dispatch((1, 2, 3))
show_dispatch({"a": "b"})
# 1 <class 'int'> int
# xx <class 'str'> str
# [1] <class 'list'> dispatcher
# (1, 2, 3) <class 'tuple'> tuple/dict
# {'a': 'b'} <class 'dict'> tuple/dict

cmp_to_key

cmp_to_key()用来自定义排序规则,可将比较函数(comparison function)转化为关键字函数(key function):

  • 比较函数:接受两个参数,比较这两个参数,并返回0、1或-1;
  • 关键字函数:接受一个参数,返回其对应的可比较对象;
test = [1, 3, 5, 2, 4]
test.sort(key=functools.cmp_to_key(lambda x, y: 1 if x < y else -1))
print(test) # [5, 4, 3, 2, 1]

total_ordering

是一个类装饰器,用于自动实现类的比较运算;类定义一个或者多个比较排序方法,类装饰器将会补充其余的比较方法。

被修饰的类必须至少定义 __lt__(), __le__(),__gt__(),__ge__()中的一个,以及__eq__()方法。

如,只需定义lt与eq方法,即可实现所有比较:

@functools.total_ordering
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __lt__(self, other):
        if isinstance(other, Person):
            return self.age < other.age
        else:
            raise AttributeError("Incorrect attribute!")

    def __eq__(self, other):
        if isinstance(other, Person):
            return self.age == other.age
        else:
            raise AttributeError("Incorrect attribute!")

mike = Person("mike", 20)
tom = Person("tom", 10)

print(mike < tom)
print(mike <= tom)
print(mike > tom)
print(mike >= tom)
print(mike == tom)

到此这篇关于python高阶函数functools模块的具体使用的文章就介绍到这了,更多相关python functools模块内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 树莓派(python)与arduino串口通信的详细步骤

    树莓派(python)与arduino串口通信的详细步骤

    这篇文章主要介绍了树莓派(python)与arduino串口通信的详细步骤,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-11-11
  • Python实现的爬取网易动态评论操作示例

    Python实现的爬取网易动态评论操作示例

    这篇文章主要介绍了Python实现的爬取网易动态评论操作,结合实例形式分析了Python针对网易评论正则爬取及json格式数据转换、提取等相关操作技巧,需要的朋友可以参考下
    2018-06-06
  • python leetcode 字符串相乘实例详解

    python leetcode 字符串相乘实例详解

    这篇文章主要介绍了python leetcode 字符串相乘的示例代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09
  • 如何用python 操作MongoDB数据库

    如何用python 操作MongoDB数据库

    这篇文章主要介绍了如何用python 操作MongoDB数据库,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下
    2021-04-04
  • Python利用appium实现模拟手机滑动操控的操作

    Python利用appium实现模拟手机滑动操控的操作

    Appium 是一个开源、跨平台的自动化测试工具,用于测试原生和轻量移动应用,支持 iOS, Android 和 FirefoxOS 平台。本文将利用appium实现模拟手机滑动操控的操作,感兴趣的可以了解一下
    2022-07-07
  • Python collections模块的使用技巧

    Python collections模块的使用技巧

    Python的最大优势之一是其广泛的模块和软件包。这将Python的功能扩展到许多受欢迎的领域,包括机器学习、数据科学和Web开发等, 其中最好的模块之一是Python的内置collections 模块。
    2021-04-04
  • python 动态获取当前运行的类名和函数名的方法

    python 动态获取当前运行的类名和函数名的方法

    这篇文章主要介绍了python 动态获取当前运行的类名和函数名的方法,分别介绍使用内置方法、sys模块、修饰器、inspect模块等方法,需要的朋友可以参考下
    2014-04-04
  • 使用pandas read_table读取csv文件的方法

    使用pandas read_table读取csv文件的方法

    今天小编就为大家分享一篇使用pandas read_table读取csv文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-07-07
  • Python中json模块load/loads方法实战以及参数详解

    Python中json模块load/loads方法实战以及参数详解

    经常在Python中对JSON格式的文件进行操作,今天对这些操作做一个总结,下面这篇文章主要给大家介绍了关于Python中json模块load/loads方法实战以及参数的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • 解决Python字典写入文件出行首行有空格的问题

    解决Python字典写入文件出行首行有空格的问题

    下面小编就为大家带来一篇解决Python字典写入文件出行首行有空格的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09

最新评论