一等函数

一等函数满足:

  - 在运行时创建

  - 能赋值给变量或数据结构中的元素

  - 能作为参数传给函数

  - 能作为函数的返回结果

 

把函数视作对象,并通过参数传递:

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

fact = factorial

print('factorial:',type(factorial))

print(list(map(fact,range(11))))

输出:

factorial: <class 'function'>
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800]

 

一些高阶函数:

# filter根据传入函数返回值为True还是False进行过滤,过滤掉False的
# 返回一个生成器

print('filter with lambda:',list(filter(lambda n: n % 2 != 0, range(6))))


def odd(x):

    return x % 2 != 0


print('filter with odd:',list(filter(odd,range(6))))

# reduce根据传入函数对可迭代对象的所有元素进行运算
# 返回一个生成器

from functools import reduce


def add(x,y):
    return x + y


print('reduce with add:',reduce(add, range(101)))

# 如果每个元素都是真,all返回True,all([])返回True

l = [True,True,True]

print('all with [True,True,True]:',all(l))

l = [True,True,False]

print('all with [True,True,False]:',all(l))

l = []

print('all with []:',all(l))

# 只要iterable中有元素为真,any就返回True,any([])返回False

l = [False,False,False]

print('any with [False,False,False]:',any(l))

l = [True,False,False]

print('any with [True,False,False]:',any(l))

l = []

print('any with []:',any(l))

输出:

filter with lambda: [1, 3, 5]
filter with odd: [1, 3, 5]
reduce with add: 5050
all with [True,True,True]: True
all with [True,True,False]: False
all with []: True
any with [False,False,False]: False
any with [True,False,False]: True
any with []: False

 

用户定义的可调用类型

  - 任何Python对象都可以表现得像函数。为此,只需实现实例方法__call__

  - 判断一个对象是否可调用,使用内置callable()函数

import random


class BingoCage:

    def __init__(self,items):

        self._items = list(items)
        random.shuffle(self._items)

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

    def __call__(self, *args, **kwargs):
        return self.pick()


bingoCage = BingoCage(list(range(10)))

print('is bingoCage callable:',callable(bingoCage))

for i in range(10):
    print(bingoCage(),end=' ')

输出:

is bingoCage callable: True
2 9 0 8 4 1 6 5 3 7

 

函数的参数

  - 参数分类

    - 定位参数:调用时通过位置匹配实参

    - 关键字参数:调用时通过位置或参数名称匹配实参

    - 仅限关键字参数:调用时只能通过参数名称匹配实参

    - 未命名的定位参数:匹配多个连续的定位参数,将他们放进一个元组,形如 *args

    - 未命名的关键字参数:匹配多个连续的仅限关键字参数,将他们放进一个dict,形如 **kwargs

  - 参数顺序

    - 定位参数、关键字参数、未命名的定位参数(或者只写一个*号用于占位),仅限关键字参数、未命名的关键字参数

def say_hello(pos1, pos2=2, *args, kw_only=3, **kwargs):

    print('定位参数和关键字参数:pos1 = %s,pos2 = %s' % (pos1, pos2))
    print('未命名的定位参数:args = ', args)
    print('仅限关键字参数:kw_only = ', kw_only)
    print('未命名的关键字参数:kwargs = ', kwargs)


say_hello(0,1,2,3,4,5,kw_only=6,name='zhangsan',age=7)

输出:

定位参数和关键字参数:pos1 = 0,pos2 = 1
未命名的定位参数:args = (2, 3, 4, 5)
仅限关键字参数:kw_only = 6
未命名的关键字参数:kwargs = {'name': 'zhangsan', 'age': 7}

 

获取关于参数的信息

def say_hello(pos1, pos2=2, *args, kw_only=3, **kwargs):

    inner = 1

    print('定位参数和关键字参数:pos1 = %s,pos2 = %s' % (pos1, pos2))
    print('未命名的定位参数:args = ', args)
    print('仅限关键字参数:kw_only = ', kw_only)
    print('未命名的关键字参数:kwargs = ', kwargs)


# __defaults__包括关键字参数的默认值
print(say_hello.__defaults__)

print('-' * 100)

# __kwdefaults__包括仅限关键字参数的默认值
print(say_hello.__kwdefaults__)

print('-' * 100)

# co_name就是函数名
print(say_hello.__code__.co_name)

print('-' * 100)

# co_varnames包括了形参和内部变量
print(say_hello.__code__.co_varnames)

输出:

(2,)
----------------------------------------------------------------------------------------------------
{'kw_only': 3}
----------------------------------------------------------------------------------------------------
say_hello
----------------------------------------------------------------------------------------------------
('pos1', 'pos2', 'kw_only', 'args', 'kwargs', 'inner')

 

函数注解

  - 在函数声明中为参数和返回值附加元数据

  - 注解可以是类或者字符串

  - python只把注解存储在函数的__annotations__属性里,什么其他操作都不做

def say_hello(pos1: str,pos2: 'pos2') -> str:

    pass


print(say_hello.__annotations__)

输出:
{'pos1': <class 'str'>, 'pos2': 'pos2', 'return': <class 'str'>}

 

posted @ 2019-02-20 21:45  StackNeverOverFlow  阅读(170)  评论(0编辑  收藏  举报