流畅的python第五章, 一等函数

从这一章开始, 就进入的新的部分, 把函数视为对象


一等函数


一等对象, 一等特性

什么是一等对象? 为什么函数在有些语言中不是一等对象? 函数你要问问你自己, 你到底比对象少了什么?

  • 能在运行时创建
  • 能赋值给变量或者数据结构中的元素
  • 能作为参数传递给函数
  • 能作为函数的返回结果

有了这三条, 才能说是一等对象, 下面我们就展示一下一等特性

# coding=utf-8
def test_func(args=None):
    """这里是doc文档"""
    print 'hello world'
    return args * (-1)
# 运行时创建
test = test_func
print test.__doc__
# 作为参数传给函数
# map( function(param), iterable):
#	return iterable
print map(test, range(10))

执行结果
执行结果


高阶函数

什么是高阶函数? 这个名字听着有点牛逼啊, 凡是听着牛逼的,实际上其实都不牛逼
让我们来看看这个高阶函数的定义到底是什么?
接受函数作为参数, 或者把函数作为结果返回的函数就是高阶函数
看了是不是就是脱了裤子放屁? python默认不就支持这样做吗?在java8里面, 接口能有个默认实现了, 才出现了流式编程, 其实也不就是这么一回事儿吗?
但是这里强调的其实是运用, 例如filtermap的联合运用等,这用另外一个例子

# coding=utf-8
fruits = ['strawberry', 'fig', 'apple', 'cherry', 'raspberry', 'banana']


def first_word(x):
	return ord(x[0])


# 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
def len_cmp(x, y):
	return 1 if len(x) > len(y) else -1


# 任何单参数的函数都能作为key
print sorted(fruits, key=len)
print sorted(fruits, key=first_word)
print sorted(fruits, cmp=len_cmp)

执行结果
在这里插入图片描述
在高阶函数中最为人熟知的有map, filter, reduce, 但是有了列表推导和生成器表达式,map和filter就没那么重要了

匿名函数

匿名函数? 不就是lambda吗?没错, 就是lambda

可调用对象

其实就是能够当作函数来调用的对象, 毕竟函数都是一等对象了,那一等对象能够当函数调用岂不是一样的道理
`能够被调用``

print callable(test_func)
print callable(fruits)

其实callable()调用的是hasattr(obj, '__call__')

class ZhangLi(object):

    def __init__(self):
        self.word = '我是张力,昵称是力霸王'

    def __call__(self, *args, **kwargs):
        print args[0], kwargs.values()[0], self.word

a = ZhangLi()

print a('你好啊', response='我很好傻逼')

执行结果
在这里插入图片描述

函数内省

等到写博客的时候,看这个忽然间懵逼了, 这是什么意思? 其实就是查看函数的内部细节

class TestClass(object):
	pass


def TestFunc(a, b):
	pass


print TestFunc.__code__.co_varnames
for item in dir(TestFunc.__code__):
	print item

执行结果
在这里插入图片描述
在这里插入图片描述

还有一些库, 看一下算了

# 参数数量
print func_test.__code__.co_argcount
# 参数名称
print func_test.__code__.co_varnames
import inspect

print inspect.getargspec(func_test)

支持函数式编程的包

operator模块

metro_data = [
    ('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),
    ('Delhi', 'JP', 36.933, (35.689722, 139.691667)),
    ('Mexico City', 'JP', 36.933, (35.689722, 139.691667)),
    ('New York-Newark', 'JP', 36.933, (35.689722, 139.691667)),
    ('Sao Paulo', 'JP', 36.933, (35.689722, 139.691667))
]
cc_name = itemgetter(0, 1)
for item in metro_data:
    print cc_name(item)

print cc_name(range(1, 10))

在这里插入图片描述
那不如我们自己手动实现一个itemgetter

def my_item_getter(*args):
	def func(array):
		result = [array[item_index] for item_index in args]
		return tuple(result)
	return func
metro_data = [
	('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),
	('Delhi', 'JP', 36.933, (35.689722, 139.691667)),
	('Mexico City', 'JP', 36.933, (35.689722, 139.691667)),
	('New York-Newark', 'JP', 36.933, (35.689722, 139.691667)),
	('Sao Paulo', 'JP', 36.933, (35.689722, 139.691667))
]
cc_name = my_item_getter(0, 1)
for item in metro_data:
	print cc_name(item)

print cc_name(range(1, 10))

在这里插入图片描述

下面的是随手写的

def test_func(args=None):
    """这里是doc文档"""
    print 'hello world'
    return args


print test_func.__doc__
print type(test_func)



# all和any,全部/只要有 真值,返回True, false
print all(range(1, 10))
print any(range(0, 1, 1))

猜你喜欢

转载自blog.csdn.net/qq_40666620/article/details/111655935