Python编程:一等函数

1.把函数作为对象

        Python函数就是对象,下面以一个例子简要介绍一下。其中,map函数返回的是一个可以迭代的对象,里面的元素是把第一个参数(一个函数)作用到第二个参数(一个可以迭代的对象)中各个元素上得到的结果。

def factorial(n):
    """return n!"""
    return 1 if n<2 else n*factorial(n-1)

a = factorial(42)
b = map(factorial, range(11))
print(a, b)
print(factorial.__doc__)
print(type(factorial))

2.高阶函数

        接受函数作为参数,或者把函数作为结果返回的函数是高阶函数。像sorted函数就是,任何单参数函数都可以作为key参数的值。但有些高阶函数,在新的Python版本中有了更好的替代。如:map和filter函数可以用之前说到的生成器表达式来替代,用reduce函数求和,现在可用sum函数来进行替代。reduce和sum函数的通用思想都是把某个操作连续应用到序列的元素上,累计之前的结果,把一系列值归约成一个值。

       类似的,all和any内置函数也是归约函数。all(iterable)中iterable参数中的每一个值都是真值才返回True,any(iterable)中iterable参数中有一个值是真值,就返回Ture。

3.匿名函数

       lambda关键字在Python表达式内构建匿名函数。lambda 函数可以接收任意多个参数 (包括可选参数) 并且返回单个表达式的值。先简要介绍一下lambda表达式。

lambda [arg1 [ ,arg2,.. . ..argn]]:expression

       在lambda表达式中,冒号前的参数可以是一个也可以是多个,冒号后的表达式只有一个。该函数是将冒号前的参数带入到冒号后的表达式中,并返回相应的值。下面的例子中,用lambda表达式构建了一个求和函数。这里要注意的是lambda表达式创建的是一个函数对象。

#求和函数
sum1 = lambda x, y: x+y
print(sum1(1,2))
#使用lambda表达式反转拼写,然后依次排序
fruits = ['apple', 'banana', 'fig', 'pear']
a = sorted(fruits, key=lambda word : word[::-1])
print(a)

4.可调用对象以及用户定义的可调用的类型

        在Python中,调用运算符(即())除了可以用在函数上,还可以用在其他对象上,一般我们用内置的callable()函数查看一个对象可不可以被调用。差不多有7中可以调用的对象。

用户定义的函数 用def语句和lambda表达式创建
内置函数 使用C语言创建的函数,如:len
内置方法 使用C语言实现的方法,如:dict.get
方法 在类的定义体中定义的函数
使用Class创建
类的实例 如果类定义了_call_方法,它的实例就可调用
生成器函数 使用yeild关键字生成的函数和方法

5.函数内省

        除了_doc_,函数对象还有许多属性。使用dir函数可以得知某个函数所具有的属性。

print(dir(sorted))

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

       Python3中进一步提供了仅限关键字参数,与之密切相关的是,调用函数时使用*和**“展开”可迭代对象,映射到单个参数。

def tag(name, *content, cls=None, **attrs):
    """生成一个或多个HTML标签"""
    if cls is not None:
        attrs['class'] = cls
    if content:
        return '\n'.join('<%s>%s' % (name, c, name) for c in content)

        第一个参数后面的人一个参数会被*content捕获,存入一个元组。tag函数中没有明确指定名称的关键字参数会被**attrs捕获,存入一个字典当中。

7.函数注释

        Python中提供了一种句法,用于为函数声明中参数和返回值附加元数据。

def clip(text: str, max_len: 'int>80') -> str:
    end = None
    if len(text) > max_len:
        space_before = text.rfind('', 0, max_len)
        if space_before >= 0:
            end = space_before
        else:
            space_after = text.rfind('', max_len)
            if space_after >= 0:
                end = space_after
    # 未找到空格
    if end is None:
        end = len(text)
    return text[:end].rstrip()

        函数声明中的各参数可以在:之后添加注解表达式。如果参数有默认值的话,注解放在参数名和等号之间。如果想注解返回值,在)和函数声明的末尾之间添加->和一个表达式。上面的例子中,text是一个字符串,max_len最大为80个整型,最后->str表示返回值为字符串。

        此外,Python .rfind() 返回字符串最后一次出现的位置(从右向左查询),如果没有匹配项则返回-1。

str.rfind(str, beg=0, end=len(string))

参数:str -- 查找的字符串,beg -- 开始查找的位置,默认为 0,end -- 结束查找位置,默认为字符串的长度。

8.支持函数式编程的包

8.1operator模块

        在函数式编程当中,经常需要把算术运算符当做函数使用。我们经常会用到的是reduce函数。下面给一个简单的例子。

from functools import reduce
from operator import mul

def fact(n):
    return reduce(mul, range(1, n+1))

print(fact(4))

        reduce() 函数会对参数序列中元素进行累积,然后返回累积得到的结果。

reduce(function, iterable[, initializer])

        其中,function -- 函数,还有两个参数,iterable -- 可迭代对象,initializer -- 可选,初始参数。

        此外,该模块中还有itemgetter函数,最常见的用途即:根据元组的某个字段给元组进行排序。attrgetter函数,它创建的函数会根据名称提取对象的属性。并返回提取值构成的元组。

8.2使用functools.partial冻结参数

        functools.partial这个高阶函数用于部分应用的一个函数。基于一个函数创建一个新的可调用的对象,把原函数的某些参数固定。

from functools import partial
from operator import mul

triple = partial(mul, 3)
print(triple(7))

       上述例子中,将一个需要两参数的函数转换成单参数,即固定了一个相乘的参数为3。

你可能感兴趣的:(python)