• python 一等函数


    一等函数

    首先要明确一等对象的概念,一等对象是一个编程语言里的概念,满足以下条件:

    1. 在运行时创建
    2. 能赋值给变量或者是数据结构中的元素
    3. 能作为参数传给函数
    4. 能作为函数的返回结果

    在python中,常常把“函数视作一等对象”称为“一等函数”。

    下例是把函数视为对象的一个例子:

    def foo(n):
        return n
    tmp = foo
    tmp(1)
    

    高阶函数

    接受函数为参数或者把函数作为返回结果的就是高阶函数。sorted是一个例子:

    def reverse(word):
        return word[::-1]
    sorted(tmp, key=reverse)
    

    上例的意思是按照reverse后的字典序给tmp这个列表排序。

    在python3中比较常见的高阶函数还有map, filter, reduce,但是在python3中一般存在更好的方式替换这三种函数。

    # map
    list(map(foo, range(6)))
    [foo(n) for n in range(6)]
    # filter
    list(map(foo, filter(lambda n: n % 2, range(6))))
    [foo(n) for n in range(6) if n % 2]
    

    可见,map和filter的直接替代品是生成器表达式。而reduce在python3中不再是内置函数,而是被放到了functools中:

    reduce的通用思想是:把某个操作作用到序列的元素上,把一系列的值聚合成一个值。reduce菜鸟教程

    类似的内置函数有sum,any,all

    1. sum 求一个序列的值的和
    2. any(iterable) 只要iterable中有一个True,返回True
    3. all(iterable) iterable中的值都是True时,返回True

    匿名函数

    lambda关键字在python表达式中创建匿名函数。lambda中的定义体不能赋值,也不能使用try,while等语句

    python中除非要作为参数传给高阶函数,否则尽可能不使用lambda函数。

    可调用对象

    除了用户定义的函数,可调用运算符也可以应用到其他对象上。可以使用callable判断是否可以调用。

    1. 用户定义的函数:使用def或者lambda创建
    2. 内置函数:使用C语言实现的函数
    3. 内置方法:dict.get
    4. 方法:在类的定义体中定义的函数
    5. 类:调用一个类时__new__->init
    6. 类的实例:如果类定义了__call__方法,那么它的实例也可以被调用。

    接下来说明如何把类的实例变成可调用的对象

    用户定义的可调用类型

    任何实现了__call__的python对象都可以被调用。

    函数内省

    dir()

    列出常规对象没有而函数有的属性,计算两个属性集合的差集即可

    从定位参数到仅限关键字参数

    调用函数时使用*和**展开可迭代对象,映射到单个参数。

    def tag(name, *content, cls=None, **attrs):
        if cls is not None:
            attrs['class'] = cls
        if attrs:
            attr_str = ''.join(" %s=%s"%(attr, value) for attr, value in sorted(attrs.items()))
        else:
            attr_str = ''
    
        if content:
            return '
    '.join("<%s%s>%s</%s>"%(name, attr_str, c, name) for c in content)
        else:
            return '<%s%s />'% (name, attr_str)
    
    

    简单理解就是,有名的参数被attr捕获,没有名字的参数被content捕获。

    获取参数相关的信息

    获取函数的签名,可以使用inspect模块:

    from inspect import signature
    sig = signature(foo)
    

    其中,__defaults__元组保存定位参数和关键字参数的默认值。code.co_varnames保存参数名称。这样获取参数信息的问题在于这两个元组中的顺序不定,所以使用signature,生成一个有序映射,把参数名称和参数默认值一一对应起来。

    而且signature中有一个bind方法,可以在参数传入函数之前进行格式的检查,如果确实必要的参数,会抛出TypeError,提示缺少参数。

    函数注解

    先来看一个有注解的函数:

    def clip(text: str, max_len: 'int > 0' = 80) -> str:
        ......
    

    参数的注解放在默认值前,冒号之后,返回值的注解在右括号后加一个箭头和返回值类型。注解不会进行任何处理,只会存在__annotations__中。

    注意!!不会进行任何处理的意思是python只会把它当做一堆字串保存起来,仅作为参考的metadata使用,不会做类型检查,不做强制验证,不做类型验证。目前,只有signature函数知道如何提取注解。

    sig.parameters
    

    parameters是一个字典,建立参数名与参数注解的映射关系。

    如果忘记了,直接看dir即可。

    实际上,functools是一个非常有用的包,我们会在之后对其进行更深入的学习~

  • 相关阅读:
    MongoDB时间处理问题
    TextArea里Placeholder换行问题
    C# 文件与二进制流间的转换
    WPF图标旋转的动画
    ABP之本地化/多语言支持
    ABP之应用服务层Application
    ABP之创建实体
    关于Mapper not initialized的错误
    Request verb is GET. It should be Post(ABP使用api访问错误)
    在ABP模板工程中使用MySQL
  • 原文地址:https://www.cnblogs.com/LuoboLiam/p/15055078.html
Copyright © 2020-2023  润新知