python入门系列:函数

引言

将一段代码集中到一块,起一个名字,下次可以根据这个名字再次使用这个代码块。

作用:

方便代码重用

分解任务,简化程序逻辑

使代码更加模块化

函数的参数

所有的传参方式都是传引用,注意列表做参数和数值做参数容易出现的问题。

单个参数

多个参数

# 定义方式

def funName(arg1, arg2, arg3...):

pass

# 调用方法

funName(arg1, arg2, arg3...) # 形参和实参一一对应

funName(arg2=v2, arg3=v3, arg1=v1) # 指明形参的名称,不用严格按照形参顺序

不定长参数

# 1. 利用元组的拆包装包

def mySum(*args):

print(type(args)) #

print(args) # (1, 2, 3, 4)

print(*args) # 拆包操作 1, 2, 3, 4

for v in args:

# todo ...

"""

装包,将传入的参数装入一个元组中,args就成了一个元组对象

拆包,将一个元组中的元素拆分出来,*args就成了参数序列

"""

# 2. 利用字典的键值对

def myInfo(**args):

print(type(args)) #

# todo ...

myInfo(name="MetaTian", age=21)

默认参数

"""

调用某些函数时,可以省略某些参数,采用定义函数时指定的值

若不省略,则以调用时传入的值为准

"""

def sorted(iterable, reverse=False):

pass

new_list = sorted([1, 3, 2, 5])

new_list = sorted([1, 3, 2, 5], True)

返回值

返回语句标志着函数的结束,一个函数最好只有一处返回语句

如果想返回多个数据,可以把数据包装成一个集合,整体返回(列表,元组,字典...)

def funName():

data = {}

# todo...

return data

偏函数

对于一个默认值较多的函数,有时我们需要重复用到其中的部分默认值,每次指定默认值比较麻烦。

可以将其中的默认值先赋值好,然后封装成一个新的函数,这就是偏函数。

import functools

numStr = "100010"

res = int(numStr, base=2)

print(res) # 34

int2 = functools.partial(int, base=2) # 重新封装,构成偏函数

print(int2(numStr)) # 34

高阶函数

一个函数的参数可以是另外一个函数

def calculate(a, b, cal_fun):

print(cal_fun(a, b))

def sum(a, b):

return a + b

def sub(a, b):

return a - b

calculate(2, 3, sum) # 5

calculate(2, 3, sub) # -1

匿名函数

lambda表达式

没有名字的函数

"""

lambda arguments: expression

冒号前面是参数,后面是要返回的表达式

"""

res = (lambda x, y : x + y)(1, 2)

print(res) # 3

fun = lambda x, y : x + y

print(fun(2, 3)) # 5

# 更多的是配合 map(), reduce()等函数进行使用

闭包

在函数嵌套定义的前提下

内层函数引用了外层函数的变量

外层函数把内层函数当做返回值

def line_config(content, length):

define line():

print(content * length)

return line

line1 = line_config("-", 5);

line2 = line_config("*", 6)

line1(); # -----

line2(); # ******

作用域问题:内层函数要修改外层函数的变量,要使用nonlocal进行声明,否则变量属于内层函数。

def test():

num = 10

def test2():

nonlocal num # test中的 num被修改

num = 666

return test2

当内层函数使用外层的变化量时,注意值的情况

def test():

funs = []

for i in range(1, 4):

def test2():

print(i)

funs.append(test2)

return funs

"""

函数在运行时才会去确定变量的值

运行时,索引 i 的值因定义时迭代完成,不再发生变化

细节请参考迭代器部分

"""

myFuns = test()

myFuns[0]() # 3

myFuns[1]() # 3

myFuns[2]() # 3

装饰器

在调用目标函数之前,对这个函数对象进行装饰(增加一些其他功能)。

函数的名字不能改变。

函数体内部的代码不能发生改变。

使用案例

def check(func):

def inner():

print("登录验证...")

func()

return inner()

# 在 fss()和 ftp()执行之前,都会送入 check()进行包装

@check # 只要python解释器执行到了这行代码就会进行装饰执行

def fss():

print("发说说")

# 上面三行等价于 fss = check(fss)

@check

def ftp():

print("发图片")

# 上面三行等价于 ftp = check(ftp)

# 主业务逻辑如下:

flag = 1

if flag == 1:

fss() # 登录验证...

else: # 发说说

ftp()

多个装饰器的调用顺序

def one(func):

print('----1----')

def two():

print('----2----')

func()

return two

def a(func):

print('----a----')

def b():

print('----b----')

func()

return b

@one

@a

def demo():

print('----3----')

demo()

# 运行结果 //从下到上装饰,从上到下执行,分析略

----a----

----1----

----2----

----b----

----3----

对带有参数的函数进行装饰

def zsq(funcs):

def inner(*args, **kwargs): # 装包

print("-" * 5)

func(*args, **kwargs) # 拆包

return inner

@zsq

def fun1(n1, n2, n3):

print(n1, n2, n3)

@zsq

def fun2(n):

print(n)

fun1(1, 2, n3=8) # 1 2 8

fun2(3) # 3

对带有返回值的函数进行装饰

def zsq(funcs):

def inner(*args, **kwargs): # 装包

print("-" * 5)

res = func(*args, **kwargs) # 拆包

return res

@zsq

def fun1(n1, n2, n3):

return sum(n1, n2, n3)

fun1(1, 2, 3)

带有参数的装饰器

def getzsq(char):

def zsq (func):

def inner():

print(char * 5)

func()

return inner

return zsq

@getzsq("*")

def f(): # *****

print("666") # 666

@getzsq("-")

def f1(): # -----

print("666") # 666

生成器

是一个特殊的迭代器

特性:

惰性计算数据,节省内存

能够记录状态,通过next()函数,访问下一个状态

使用方式

# 生成器表达式,不是元组推导,没有元组推导式

l = (i for i in range(1, 10000000) if i % 2)

print(type(l))

print(next(l)) # 1

print(next(l)) # 3

for i in l:

print(i) # 循环打印出所有满足条件的值

# 生成器函数

def test():

for i in range(1, 9):

yield i

g = test()

print(next(g)) # 1

print(next(g)) # 2

注:喜欢python + qun:839383765 可以获取Python各类免费最新入门学习资料!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190214A0DB1B00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券