python采用函数式_python -- 函数以及函数式编程

函数以及函数式编程

到目前为止,我们的Python 代码已经实现了小的分块。它们都适合处理微小任务,

但是我们想复用这些代码,所以需要把大型代码织成可管理的代码段。代码复用的第一步是

使用函数,它是命名的用于区分的代码段。函数可以接受任何数字或者其他类型的输入作为参

数,并且返回数字或者其他类型的结果。

定义一个函数

为了定义Python 函数,你可以依次输入def、函数名、带有函数参数的圆括号,最后紧跟一个

冒号(:)。函数命名规范和变量命名一样(必须使用字母或者下划线_ 开头,仅能含有字母、

数字和下划线)。

我们先定义和调用一个没有参数的函数。下面的例子是最简单的Python 函数:

>>> def do_nothing():

... pass

定义一个无参数函数

现在,定义一个无参数,但打印输出一个单

词的函数:

>>> def make_a_sound():

... print('momoda')

...

>>> make_a_sound()

momoda

>>> def agree():

... return True

...

#或者,调用这个函数,使用if 语句检查它的返回值:

>>> if agree():

... print("Is true")

... else:

... print("Is Flase")

...

Is true

定义一个有参函数

>>> def echo(str):

... return str*2

...

>>> echo('abc')

'abcabc'

>>>

def fruit_color(color):

if color == 'red':

print('这可能是一个苹果,或者是西红柿')

elif color == 'yellow':

print('这或许是一个香蕉也说不定')

elif color == 'blue':

print('一定是蓝莓吧')

else:

print('我可猜不到这是什么')

fruit_color('red')

位置参数

下面创建一个带有位置参数的函数,并且返回一个字典:

def menu(a,b,c):

return {'a':a,'b':b,'c':c}

print(menu('a','b','c’))

{'a': 'a', 'b': 'b', 'c': 'c’}

#尽管这种方式很常见,但是位置参数的一个弊端是必须熟记每个位置的参数的含义。在调

#用函数menu() 时误把最后一个参数当作第一个参数,会得到完全不同的结果:

print(menu('c','b','a'))

{'c': 'a', 'b': 'b', 'a': 'c'}

关键字参数

为了避免位置参数带来的混乱,调用参数时可以指定对应参数的名字,甚至可以采用与函

数定义不同的顺序调用:

def menu(a,b,c):

return {'a':a,'b':b,'c':c}

print(menu(c='c',b='b',a='a’))

当然也可以混合使用

def menu(a,b,c):

return {'a':a,'b':b,'c':c}

print(menu(a='a',c='c',b='b'))。

指定默认参数值

举例:

def menu(a,b,c):

return {'a':a,'b':b,'c':c}

print(menu(c='b',b='a’))

报错,缺少参数,实际上我们可以设置参数默认值

def menu(a='a',b='b',c='c'):

return {'a':a,'b':b,'c':c}

print(menu(c='b',b='a’))

print(menu())

使用*收集位置参数

当参数被用在函数内部时, 星号将一组可变数量的位置参数集合成参数值的元组。

def my_print(*Str):

print(Str)

my_print()

()

my_print(1,2,3,4,5):

(1, 2, 3, 4, 5)

my_print(1,2,3,'let\'s go’)

(1, 2, 3, "let's go")

使用两个星号可以将参数收集到一个字典中,参数的名字是字典的键,对应参数的值是字

典的值。下面的例子定义了函数print_kwargs(),然后打印输出它的关键字参数:

def my_print(**abc):

print(abc)

my_print(a='a',b='b',c='c')

函数本身也是一个对象

之前提过Python 中一切都是对象,包括数字、字符串、元组、列表、字典和函数。函数是Python 中的一等公民,可以把它们(返回值)赋给变量,可以作为参 数被其他函数调用,也可以从其他函数中返回值。它可以帮助你在Python 中实现其 他语言难以实现的功能。

#为了测试,现在定义一个简单的函数answer(),它没有任何参数,仅仅打印输出数字42:

>>> def answer():

... print(42)

#运行该函数,会得到下面的结果:

>>> answer()

42

#再定义一个函数run_something。它有一个参数func,这个参数是一个可以运行的函数的名字:

>>> def run_something(func):

... func()

#将参数answer 传到该函数,在这里像之前碰到的一样,把函数名当作数据使用:

>>> run_something(answer)

42

########################################

#我们来运行一个带参数的例子。定义函数add_args(),它会打印输出两个数值参数(arg1和arg2)的和:

>>> def add_args(arg1, arg2):

... print(arg1 + arg2)

#那么,add_args() 的类型是什么?

>>> type(add_args)

#此刻定义一个函数run_something_with_args(),它带有三个参数:

#• func——可以运行的函数

#• arg1——func 函数的第一个参数

#• arg2——func 函数的第二个参数

>>> def run_something_with_args(func, arg1,arg2):

add_args(arg1, arg2)

>>> run_something_with_args(add_args, 5, 9)

14

内部函数

内部函数可以看作一个闭包。闭包是一个可以由另一个函数动态生成的函数,并且可以改变和存储函数外创建的变量的值。

>>> def outer(a, b):

... def inner(c, d):

... return c + d

... return inner(a, b)

...

>>>

>>> outer(4, 7)

11

#########################

def fun5():

def sayhello(name):

print("hello ", name)

return sayhello #返回的是函数名称

fun5()("zhangsan")

匿名函数:lambda()函数

edit_story(stairs, lambda word: word.capitalize() + '!')

map

map(funcname, list)

map(function, sequence[, sequence, ...]) -> list:将function作用于给定序列的每一个元素,

并将结果作为list返回;如果函数中需要多个参数则从多个序列中读取(python3里面,map()

的返回值已经不再是list,而是iterators, 所以想要使用,只用将iterator 转换成list 即可)

def square(x):

return x**2

map(square, [1,2,3,4,5])

f1 = lambda x:x**2 #lambda表达式就是一个匿名函数

print(f1(3))

i1 = map(f1, [1,2,3,4,5])

print(list(i1))

reduce

reduce(function, sequence[, initial]) -> value:与map相比 , reduce类似于一个聚合类的

应用方法, 把list中的参数, 依次传递给funcname, 每次funcname的参数都是上个funcname

执行结果和下一个list中的元素, 所以, funcname 的 参数必须是两个. 从执行过程看, 有点像递

归.如果指定了initial则首先从此值和第一个元素开始计算。

def sum(x,y):

return x+y

print(functools.reduce(sum, [1, 2, 3, 4, 5]))

print(functools.reduce(lambda x,y:x+y, [1,2,3,4,5]))

print(functools.reduce(lambda x,y:max([x,y]), [1,2,3,4,5]))

filter()

filter(function or None, sequence) -> list,tuple,string:

调用一个布尔类型的函数来迭代遍历每个seq中的元素,返回使得func返回为true的

元素的序列。

print(list(filter(lambda x:isinstance(x, (int)), [1,2,"3"])))

print(list(filter(lambda x:x>2, [1,2,3])))

sorted

sorted( list, [comp_func])

排序方法, 第二个是可选参数, 根据可选参数返回的值, 对结果进行排序, comp_func

接受两个参数(x, y), 最终返回的结果应该是-1.0,1, 如果返回的是-1, 表示x , 0表示x=y,

1表示x>y, 所以, 实际的排序可以自定义

print(sorted([4,6,1,2,3]))

print(sorted([4,6,1,2,3], reverse=True))

print(sorted([1,2,3,4,5,6],key=cmp_to_key(lambda x,y:y-x)))

命名空间和作用域

一个名称在不同的使用情况下可能指代不同的事物。Python 程序有各种各样

的命名空间,它指的是在该程序段内一个特定的名称是独一无二的,它和其他同名的

命名空间是无关的。每一个函数定义自己的命名空间。如果在主程序(main)中定义

一个变量x,在另外一个函数中也定义x 变量,两者指代的是不同的变量。

每个程序的主要部分定义了全局命名空间。因此,在这个命名空间的变量是

全局变量。

animal = 'cat'

>>> def print_global():

. . . print('inside print_global:',animal)

. . .

>>> print('outside print_global:',animal)

outside print_global: cat

>>> print_global()

inside print_global: cat

####################

#在函数中改变全局变量,会报错:

>>> def change_and_print_global():

... print('insid

change_and_print_global:',animal)

... animal = 'dog'

... print('after the change:',animal)

...

>>> change_and_print_global()

Traceback (most recent call last):

File "", line 1, in

File "", line 2, in

change_and_print_global

UnboundLocalError: local variable

'animal' referenced before assignment

如果在函数中不声明关键字global,Python 会使用局部命名空间,同时变量也是局

部的。函数执行后回到原来的命名空间。

Python 提供了两个获取命名空间内容的函数:

• locals() 返回一个局部命名空间内容的字典;

• globals() 返回一个全局命名空间内容的字典。

生成器

生成器是用来创建Python 序列的一个对象。目的就是为了避免一下子生成的数据太多占用大量内存,生成器会在数据被用到时生成数据。

def my_range(first, last, step=1):

n = first

while n

yield n #yield是一个关键字,使用yeild的函数实际上一个生成器

n+=step

print(my_range())

#

装饰器

名称中_和__的用法

以两个下划线__ 开头和结束的名称都是Python 的保留用法。因此,在自定义的变量

中不能使用它们。选择这种命名模式是考虑到开发者一般是不会选择它们作为自己的

变量的。

if __name__ == '__main__':

print("这里是入口")

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值