python学习笔记之 函数间接调用 lambda 以及内置函数

1 函数的间接调用

在python,一切都是对象,函数也和其他对象一样,可以赋值给其他的名字、传递给其他函数、嵌入到数据结构。

而函数名直接是一个对象的引用。

  • 赋给其他名字
def echo(message):
    print(message)
    
echo('direct call')
x = echo
x('Indirect call')
  • 传递给其他函数
def indirect(func, arg):
    func(arg)

indirect(echo, 'argument call')
  • 把函数对象的内容填入数据结构
schedule = [(echo,'spam'),(echo, 'ham')]
for (func, arg) in schedule:
    func(arg)

2 函数属性

2.1 函数内省

函数对象也有着属性

>> func.__name__
'func'

>> dir(func)
['__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__']

>>dir(func.__code__)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'co_argcount', 'co_cellvars', 'co_code', 'co_consts', 'co_filename', 'co_firstlineno', 'co_flags', 'co_freevars', 'co_kwonlyargcount', 'co_lnotab', 'co_name', 'co_names', 'co_nlocals', 'co_posonlyargcount', 'co_stacksize', 'co_varnames', 'replace']

2.2 函数附加属性

函数不仅仅只有python原来自带的属性,还可以通过自己附加属性,

func.count = 0
func.count += 1

2.3 函数注解

函数注解通常编写在def头部

def func(a:'spam', b:(1,10), c:float) -> int:
    return a+b+c

>> func(1,2,3)
6

调用一个注解过的函数和以前一样。但是当注解出现时,python将之收集到字典种,参数名变成键,注解变成值

>>> func.__annotations__
{
     'a': 'spam', 'b': (1, 10), 'c': <class 'float'>, 'return': <class 'int'>}

编写了注解后仍然能够使用默认值

def func(a:'spam'=4,b:(1,10)=5,c: float = 6) -> int:
    return a+b+c

lambda不能使用注解

3 lambda

lambda又称匿名函数,因为它不需要像def那样要函数变量名

lambda表达式

lambda arg1,arg2,argN: expression using args

3.1 为什么要使用lambda

lambda起到了函数速写的作用,允许在执行的代码嵌入函数定义。

L = [lambda x : x**2,
    lambda x : x**3,
    lambda x : x**4]

for f in L:
    print(f(2))
    
print(L[0](3))

当需要把小段的可执行代码编进def不能编进的代码中,lambda就起到了很好的作用

def f1(x): return x**2
def f2(x): return x**3
def f3(x): return x**4

L = [f1,f2,f3]

for f in L:
    print(f(2))
    
print(L[0](3))

并且通过写lambda函数可以避免函数名与其他变量名重复。

3.2 嵌套lambda和作用域

lambda 是嵌套函数作用域查找的最大受益者,通常lambda出现def中(很典型的情况)lambda可以能够获取上层函数的变量作用域。

def action(x):
    return (lambda y:x+y)

>>> act = action(99)
>>> act(2)
101

4 map和filter

4.1 序列映射函数map

程序通常有要求对列表中的每一个元素进行一个操作并将其结果集合起来。

例如,对每一个列表进行加10

counters = [1,2,3,4]

updated=[]
for x in counters:
    updated.append(x+10)

python提供了内置的工具map来完成此操作

def inc(x): return x+10

list(map(inc, counters))

map期待传入一个函数和一个列表,那么用lambda就可以避免独立成立一个函数

list(map(lambda x:x+10,counters))

当函数需要多个参数时,也可以提供多个列表来完成操作

pow(3,4)
>> 81
list(map(pow,[1,2,3],[2,3,4]))
[1,8,81]

map期待一个N参数道德函数用于N列表

4.2 filter函数

filter就是过滤器的意思,基于某一测试函数过滤一些元素

list(range(-5,5))

list(filter((lambda x:x>0),range(-5,5)))

等价于

res = []
for x in range(-5,5):
    if x >0:
        res.append(x)

4.3 reduce函数

reduce接收一个迭代器来进行处理,但是返回的说单个结果

from functools import reduce

>>> reduce((lambda x,y:x+y),[1,2,3,4])
10
>>> reduce((lambda x,y:x*y),[1,2,3,4])
24

等价于

L = [1,2,3,4]
res = L[0]
for x in L[1:]:
    res = res+x

你可能感兴趣的:(python学习笔记,python)