python高级(五)—— python函数(一等对象)
本文主要内容
一等对象
普通函数 & 高阶函数
可调用对象 & 自定义可调用类型
函数内省
函数注释
文中代码均放在github上:https://github.com/ampeeg/cnblogs/tree/master/python高级
一等对象
''' 在python中,"一等对象"指的是满足下述条件的程序实体: (1)在运行时创建 (2)能赋值给变量或数据结构中的元素 (3)能作为参数传给函数 (4)能作为函数的返回结果 整数、字符串和字典都是一等对象。在面向对象编程中,函数也是对象,并满足以上条件,所以函数也是一等对象,称为"一等函数" ''' if __name__ == "__main__": # 函数的一等性质 def foo(n): '''returns n!''' return 1 if n < 2 else n * foo(n-1) print(foo(5)) # 120 my_foo = foo print(my_foo) # <function foo at 0x1010e3f28> 能赋值给变量 print(list(map(my_foo, range(6)))) # [1, 1, 2, 6, 24, 120] 能赋值给函数 def foo2(): return foo my_foo2 = foo2() print(my_foo2(5)) # 120 可作为函数的返回结果 |
普通函数 & 高阶函数
''' 我们一般将函数分为"普通函数"和"高阶函数",接受函数为参数的函数为高阶函数,其余为普通函数 普通函数大家再熟悉不过,本文不讲,主要讲一下map、filter、reduce三个高阶函数 ''' if __name__ == "__main__": # map第一个参数接受一个函数,并将这个函数作用于后面可迭代对象的每一个元素中 l = map(lambda x : x ** 2, range(11)) # 返回的是生成器类型 print(list(l)) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100] w = map(str.upper, 'asfafasfasfaf') print(list(w)) # ['A', 'S', 'F', 'A', 'F', 'A', 'S', 'F', 'A', 'S', 'F', 'A', 'F'] # filter第一个参数也接受函数,并返回所有满足该函数的元素 l = filter(lambda n: n % 2, range(10)) # 返回n % 2为真的数,就是奇数 l2 = filter(lambda n: n % 2 ==0, range(10)) # 返回偶数 print(list(l)) # [1, 3, 5, 7, 9] print(list(l2)) # [0, 2, 4, 6, 8] # reduce 从python3开始,reduce放在functools中 # reduce将某个操作连续应用到序列元素上,即其会将前一步的结果继续应用到下一个元素上 from functools import reduce s = reduce(lambda x,y: x + y, range(101)) print(s) # 5050 对1到100求和 |
可调用对象 & 自定义可调用类型
''' 我们在使用函数或者实例化对象的时候会用到括号(即()),这个括号实际上是调用运算符,python里面有7中可调用对象: 1、用户定义的函数 def和lambda创建 2、内置函数 使用C语言实现的函数,如len或time.strftime 3、内置方法 使用C语言实现的方法,如dict.get 4、方法 在类的定义体中定义的函数 5、类 调用类时其实首先运行的是__new__方法,然后运行__init__方法。这里很有意思,自定义类中其实没有重写__new__方法, 而是调用的超类的__new__方法,如果查看源代码的实现逻辑,相信你会有新的发现,这里不做讨论。 6、类的实例 如果类定义了__call__方法,那么它的实例可以作为函数调用 7、生长器函数 使用yield关键字的函数或方法。 ''' if __name__ == "__main__": # 创建一个自定义可调用类 class Foo(): def __init__(self): self.name = "Foo" def __call__(self, *args, **kwargs): print("调用__call__") Foo()() # 输出:调用__call__ # 以上使用 Foo()() 这种写法看上去很有意思。首先,Foo()会创建一个Foo实例,调用__init__构造方法,; 然后使用实例(),此时 # 调用__call__方法 |
函数内省
''' 函数内省我们通过例子来看 ''' if __name__ == "__main__": # 先创建一个函数 def foo(n): ''':returns n!''' return 1 if n<2 else n*foo(n-1) print(foo.__doc__) # :returns n! __doc__里面存储了注释内容 # 看看这个函数中有多少属性 print(dir(foo)) ''' ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] ''' # 下表对一些属性做了说明
|
函数注释
''' 函数注解很简单,用下面例子简单讲解即可明了 ''' if __name__ == "__main__": def foo(num: int, step: 'int 间隔(大于0小于num)'=1) -> int: ''':returns 求num的阶乘,可以设置步长''' # 这里的注释存储在__doc__中 return num if num <= step else num * foo(num-step,step) print(foo(5)) # 120 (5*4*3*2*1) print(foo(5, 2)) # 15 (5*3) # 函数声明中的各个参数可以在冒号(:)之后增加注释,该注释可以直接写参数类型,也可以写字符串 # -> 符号后面是对函数返回值进行注解 # 这些注释内容存储在属性 __annotations__中 print(foo.__annotations__) # {'step': 'int 间隔(大于0小于num)', 'num': <class 'int'>, 'return': <class 'int'>} # 这样注释后,在使用pycharm时会出现自动提示 |
python高级系列文章目录