Python3 函数

Posted yujiaershao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python3 函数相关的知识,希望对你有一定的参考价值。

python 函数相关知识

 

 

  • 定义一个函数:

  

def func(x, y):
‘‘‘
"The function definitions"
:param x: 参数x
:param y: 参数y
:return: 返回值
‘‘‘
z = x + y
return z

ret = test(1, 2)
print(ret)


def:定义函数的关键字
func: 函数名
(): 内可定义形参
"": 文件描述,函数的描述信息
z=x+y : 代码块或程序处理逻辑
return: 定义返回值
调用方法: 函数名()

 

  • 函数和过程

  过程定义:过程就是简单特殊没有返回值的函数

  这么看来我们在讨论为何使用函数的的时候引入的函数,都没有返回值,没有返回值就是过程,没错,但是在python中有比较神奇的事情

def t1():
msg = ‘t1‘
print(msg)

def t2():
msg = ‘t2‘
print(msg)
return msg

n1 = t1()
n2 = t2()

print(‘from t1 return is [%s]‘ % n1)
print(‘from t2 return is [%s]‘ % n2)
输出:

t1
t2
from t1 return is [None]
from t2 return is [t2]

 

  总结:当一个函数/过程没有使用return显示的定义返回值时,python解释器会隐式的返回None,

  所以在python中即便是过程也可以算作函数。

def test01():
pass

def test02():
return 0

def test03():
return 0, 1, ‘hello‘, [‘aa‘, ‘bb‘], {‘k1‘: ‘v1‘}

t1 = test01()
t2 = test02()
t3 = test03()

print(‘from test01 return is [%s]: ‘ % type(t1), t1)
print(‘from test02 return is [%s]: ‘ % type(t2), t2)
print(‘from test03 return is [%s]: ‘ % type(t3), t3)
输出:

from test01 return is [<class ‘NoneType‘>]: None
from test02 return is [<class ‘int‘>]: 0
from test03 return is [<class ‘tuple‘>]: (0, 1, ‘hello‘, [‘aa‘, ‘bb‘], {‘k1‘: ‘v1‘})

  总结:

     返回值数=0:返回None

     返回值数=1:返回object

     返回值数>1:返回tuple

 

  • 函数参数

  1.形参变量只有在被调用时才分配内存单元,在调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。函数调用结束返回主调用函数后则不能再使用该形参变量

  2.实参可以是常量、变量、表达式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。因此应预先用赋值,输入等办法使参数获得确定值

  技术分享图片

 

  3.位置参数和关键字(标准调用:实参与形参位置一一对应;关键字调用:位置无需固定)

  4.默认参数

  5.参数组

 

  • 局部变量和全局变量

  在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。

  全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
  当全局变量与局部变量同名时:
  在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。

  

#coding=gbk

name=‘全局变量‘

def change_name():
print(‘我的名字‘,name)

change_name()
print(name)

def change_name():
name=‘局部变量‘
print(‘我的名字‘,name)

change_name()
print(name)



def change_name():
global name
name=‘局部变量‘
print(‘我的名字‘,name)

change_name()
print(name)
输出:

我的名字 全局变量
全局变量
我的名字 局部变量
全局变量
我的名字 局部变量
局部变量

 

  global 将局部变量赋值给全局变量

 

  • 前向引用之‘函数即变量’
# 01
def action():
print(‘in the action‘)
logger()

action()
输出:
NameError: name ‘logger‘ is not defined


# 02
def logger():
print(‘in the logger‘)

def action():
print(‘in the action‘)
logger()

action()
输出:

in the action
in the logger

 

# 03
def action():
print(‘in the action‘)
logger()

def logger():
print( ‘in the logger‘)

action()
输出:

in the action
in the logger

 

 

  • 嵌套函数和作用域
#coding=gbk
name = "a1"


def change_name():
name = "a2"

def change_name2():
name = "a3"
print("第3层打印", name)

change_name2() # 调用内层函数
print("第2层打印", name)

change_name()
print("最外层打印", name)
输出:

第3层打印 a3
第2层打印 a2
最外层打印 a1

 

  作用域在定义函数时就已经固定住了,不会随着调用位置的改变而改变

 

# 01
name=‘a‘

def func1():
name=‘b‘
def func2():
print(name)
return func2

func=func1()
func()
输出:
b

# 02
name=‘a‘

def t1():
name=‘b‘
def t2():
name=‘c‘
def t3():
print(name)
return t3
return t2

func=t1()()()
输出:
c

 

  • 递归调用

  在函数内部,可以调用其他函数,如果再调用一个函数的过程中直接或者间接调用自身。就属于递归调用。

  递归特性:

  1、必须有一个明确的结束条件

  2、每次进入更深一层递归时,问题规模比上次递归都应有所减少

  3、递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减少一层栈帧。

    由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

  

# 计算1 * 2 * 3 * 4 * n 的值
def func(n):
if n == 1:
return 1
return n * func(n - 1)

ret = func(10)
print(ret)

 

 

 

  • 匿名函数 lambda

  匿名函数就是不需要显式的指定函数

def func(n):
n = n + 1
return n
print(func(4))


ret = lambda x:x+1
print(ret(4))
输出:
5
5

 

# 斐波那契数列: 0,1,1,2,3,5,8,13,,,,

def func(arg1, arg2):
if arg1 == 0:
print(arg1 ,arg2)
arg3 = arg1 + arg2
print(arg3)
return func(arg2, arg3)

func(0, 1)

  匿名函数主要和其他函数搭配使用

 

 

  • 函数式编程:

 

  函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程的程序设计。函数就是面向过程的程序设计的基本单元。

 

  而函数式编程(请注意多了一个“式”字)——Functional Programming,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算。

 

  我们首先要搞明白计算机(Computer)和计算(Compute)的概念。

 

  在计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断和跳转指令,所以,汇编语言是最贴近计算机的语言。

 

  而计算则指数学意义上的计算,越是抽象的计算,离计算机硬件越远。

 

  对应到编程语言,就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如C语言;越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Lisp语言。

 

  函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。

 

  函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!

 

  Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。

 

 

 

   高阶函数

 

  满足俩个特性任意一个即为高阶函数

 

  1.函数的传入参数是一个函数名

 

  2.函数的返回值是一个函数名

 

 

  map函数:

  处理序列中的每个元素,得到的结果是一个‘列表’,该‘列表’元素个数及位置与原来一样

 

# 求一个列表的所有元素的平方
array=[1,3,4,71,2]

ret=[]
for i in array:
ret.append(i**2)
print(ret)

#如果我们有一万个列表,那么你只能把上面的逻辑定义成函数
def map_test(array):
ret=[]
for i in array:
ret.append(i**2)
return ret

print(map_test(array))

#如果我们的需求变了,不是把列表中每个元素都平方,还有加1,减一,那么可以这样
def add_num(x):
return x+1
def map_test(func,array):
ret=[]
for i in array:
ret.append(func(i))
return ret

print(map_test(add_num,array))
#可以使用匿名函数
print(map_test(lambda x:x-1,array))


#上面就是map函数的功能,map得到的结果是可迭代对象
print(list(map(lambda x:x-1,array)))

 

 

  filter函数:

  遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来

 

 

#coding=gbk
‘‘‘
找到列表中不是sb开头的元素
代码的演变过程
‘‘‘
# 一阶 : for 循环
movice_people = [‘sb_aaa‘, ‘sb_bbb‘, ‘ccc‘, ‘sb_ddd‘]

li = []
for i in movice_people:
if not i.startswith(‘sb‘):
li.append(i)
print("一阶: ", li)

# 二阶: 定义函数
movice_people = [‘sb_aaa‘, ‘sb_bbb‘, ‘ccc‘, ‘sb_ddd‘]

def find_people(arrary):
li = []
for i in arrary:
if not i.startswith(‘sb‘):
li.append(i)
return li
ret = find_people(movice_people)
print("二阶: ", ret)

# 三阶:判断用函数实现,传入功能函数名进行处理
movice_people = [‘sb_aaa‘, ‘sb_bbb‘, ‘ccc‘, ‘sb_ddd‘]

def sb_show(n):
return n.startswith(‘sb‘)

def find_people(func, arrary):
li = []
for i in arrary:
if not func(i):
li.append(i)
return li
ret = find_people(sb_show, movice_people)
print("三阶: ", ret)

# 四阶: 利用匿名函数lambda
# def sb_show(n):
# return n.startswith(‘sb‘)
# 可以用lambda 替换:lambda n:n.startswith(‘sb‘)
movice_people = [‘sb_aaa‘, ‘sb_bbb‘, ‘ccc‘, ‘sb_ddd‘]

def find_people(func, arrary):
li = []
for i in arrary:
if not func(i):
li.append(i)
return li
ret = find_people(lambda n:n.startswith(‘sb‘), movice_people)
print("四阶: ", ret)

# 五阶: 利用filter函数
movice_people = [‘sb_aaa‘, ‘sb_bbb‘, ‘ccc‘, ‘sb_ddd‘]

ret = filter(lambda n:not n.startswith(‘sb‘), movice_people)
print("五阶: ", list(ret))

输出:

一阶: [‘ccc‘]
二阶: [‘ccc‘]
三阶: [‘ccc‘]
四阶: [‘ccc‘]
五阶: [‘ccc‘]

 

 

  • reduce函数
  处理一个序列,然后把序列进行合并操作。

 



num = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 处理一个列表所有元素的乘积

# 一阶: for循环
ret = 1
for i in num:
ret *= i
print("一阶: ", ret)

# 二阶: 使用函数
def reduce_t(array):
ret = 1
for i in array:
ret *= i
return ret
print("二阶: ", reduce_t(num))

# 三阶:使用lambda函数, 添加一个初始值。
def reduce_t(func, array, init=None):
if init == None:
ret = array.pop(0)
else:
ret = init
for i in array:
ret *= i
return ret
print("三阶: ", reduce_t(lambda x, y:x*y, num, 2))

# 四阶:reduce函数
from functools import reduce
print("四阶: ", reduce(lambda x, y:x*y, num, 2))

 

 
































































































































































































































































































































以上是关于Python3 函数的主要内容,如果未能解决你的问题,请参考以下文章

scrapy按顺序启动多个爬虫代码片段(python3)

python常用代码片段总结

VSCode自定义代码片段——声明函数

VSCode自定义代码片段8——声明函数

学习 PyQt5。在我的代码片段中找不到错误 [关闭]

使用从循环内的代码片段中提取的函数避免代码冗余/计算开销