python中的函数

在python中一切皆对象,函数也是对象。
一,函数
1,先来查看函数的有哪些属性

import pysnooper


@pysnooper.snoop()
def factorial(n):
    """
    function
    :param n:
    :return:
    """
    return 1 if n < 2 else n * factorial(n - 1)


if __name__ == '__main__':
    print(dir(factorial))
    print(type(factorial))

运行结果:

['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__wrapped__']

<class 'function'>

在 Python 中,函数是一等对象。编程语言理论家把“一等对象”定义为满足下述条件的程 序实体:
• 在运行时创建 。
• 能赋值给变量或数据结构中的元素 。
• 能作为参数传给函数 。
• 能作为函数的返回结果。

Python 函数是对象。这里我们创建了一个函数,然后调用 它,读取它的 doc 属性,并且确定函数对象本身是 function 类的实例。
doc 属性用于生成对象的帮助文本。
在这里插入图片描述
二,高阶函数
定义:接受函数为参数,或者把函数作为结果返回的函数是高阶函数。
在函数式编程范式中,最为人熟知的高阶函数有 map、filter、reduce 和 apply、sorted。apply 函 数在Python 2.3 中标记为过时,在Python 3 中移除了,因为不再需要它了。map、filter和reduce的现代替代品(由于列表推导式和列表生成器的出现,他们被替代了。)
如:
fruits = [‘strawberry’, ‘fig’, ‘apple’, ‘cherry’, ‘raspberry’, ‘banana’]
sorted(fruits, key=len)

三,匿名函数
lambda 关键字在 Python 表达式内创建匿名函数。然而,Python 简单的句法限制了lambda 函数的定义体只能使用纯表达式。换句话说, lambda 函数的定义体中不能赋值,也不能使用 while 和 try 等 Python 语句。
例如:
fruits = [‘strawberry’, ‘fig’, ‘apple’, ‘cherry’, ‘raspberry’, ‘banana’]
sorted(fruits, key=lambda word: word[::-1])
除了作为参数传给高阶函数之外,Python 很少使用匿名函数。由于句法上的限制,非平凡 的 lambda 表达式要么难以阅读,要么无法写出。

lambda 句法只是语法糖:与 def 语句一样,lambda 表达式会创建函数对象。这是Python 中几种可调用对象的一种。下面会说明所有可调用对象。

四、可调用对象
除了用户定义的函数,调用运算符(即 ())还可以应用到其他对象上。如果想判断对象能 否调用,可以使用内置的 callable() 函数。Python 数据模型文档列出了 7 种可调用对象。
1,用户定义的函数: 使用 def 语句或 lambda 表达式创建。
2,内置函数: 使用 C 语言(CPython)实现的函数,如 len 或 time.strftime。
3,内置方法: 使用 C 语言实现的方法,如 dict.get。
4,方法: 在类的定义体中定义的函数。
5,类:调用类时会运行类的 new 方法创建一个实例,然后运行 init 方法,初始化实例,最后把实例返回给调用方。因为 Python 没有 new 运算符,所以调用类相当于调用函数。(通常,调用类会创建那个类的实例,不过覆盖 new 方法的话,也可能出现 其他行为。
6,类的实例:如果类定义了 call 方法,那么它的实例可以作为函数调用。
7,生成器函数: 使用 yield 关键字的函数或方法。调用生成器函数返回的是生成器对象

Python 中有各种各样可调用的类型,因此判断对象能否调用,最安全的方法 是使用内置的 callable() 函数:
在这里插入图片描述
五, 用户定义的可调用类型
不仅 Python 函数是真正的对象,任何 Python 对象都可以表现得像函数。为此,只需实现 实例方法 call

import random


class BingoCage:
    def __init__(self, items):
        self._items = list(items)
        random.shuffle(self._items)
        print(self._items)

    def pick(self):
        try:
            return self._items.pop()
        except IndexError:
            raise LookupError('pick from empty BingoCage')

    def __call__(self):
        return self.pick()


if __name__ == '__main__':
	bingo = BingoCage(range(10))
    print(bingo.pick())
    print(bingo())
    print(callable(bingo))

运行结果:
在这里插入图片描述
实现 call 方法的类是创建函数类对象的简便方式,此时必须在内部维护一个状态,让它在调用之间可用,例如 BingoCage 中的剩余元素。装饰器就是这样。装饰器必须是函数, 而且有时要在多次调用之间“记住”某些事 [ 例如备忘(memoization),即缓存消耗大的 计算结果,供后面使用 ]。

实例对象就可以像函数一样调用了,在装饰器的时候,可以实现__call__是实现类装饰器。

六、支持函数式编程的包

虽然Guido 明确表明,Python 的目标不是变成函数式编程语言,但是得益于operatorfunctools 等包的支持,函数式编程风格也可以信手拈来。
具体包的使用下次更新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值