Python学习笔记(2-3):基础知识之函数

在这里插入图片描述

文章导读

 - 课程难度:★★☆☆☆
 - 预计学习时间:1小时
 - 简介:本节主要讲解了Python函数相关的知识,包括:(1)自定义函数的语法格式及注意要点;(2)函数的三种传参方式及返回值的设置;(3)几个重要的补充内容;
(4)三个基础函数的使用:格式转换函数、range()函数和print()函数
 - 重点涉及的函数和内容:(1)自定义函数的格式;(2)函数的作用域问题;(3)python函数没有重载;(4)int()、float()、str()函数分别将数据转换成整型、浮点型和字符串型;
(5)range()函数的基础用法及其与for循环相结合以遍历各种元素;(6)print()函数的使用

一、自定义函数

定义函数,最重要的是用来代码重用和模块化。
自定义函数的格式如下:

def 函数名(参数):
	函数体
	return 返回值

定义一个函数需要定义函数的函数名和函数体,其基本规则如下:

  • def关键字作为定义函数的声明。
  • 给出函数名。
  • 以一个圆括号指示所有的参数(也可以没有参数),参数之间以逗号,分隔。
  • 最后以冒号:结束。
  • 最后在新行开始编写函数的具体内容,即函数体,函数体的内容需要缩进。
  • 函数的默认参数。默认参数是指一个参数的默认值,函数在调用时可以不传递这个参数,直接使用定义时给出的默认值。在函数定义的时候,不能有带默认值的参数出现在无默认值参数前面的情况。
  • 函数的返回值,用return关键字标识函数最终的运行结果,返回值用逗号分隔。一个函数可以有多个返回值,也可以没有返回值。
  • 定义和调用函数时,定义参数时允许换行,传入的最后一个参数后面可以带逗号,,像列表一样,这个逗号之后没有值会被自动忽略

我们依照最后一点定义一个函数,如下:

def function(
    a = 0, 
    b = [1, 2],
    c = '567',
):
    a += 100
    b = [None]
    c = len(c)
    print(a, b, c)

# 调用这个函数:
a = 20
function(
    a = 20,
    b = [0, 1, 2],
    c = (1, 4, 7, 10),
)

这种函数的写法,虽然比较占行,但是写起来函数定义和调用参数较为清晰,可以在一些需要传递参数比较多的程序里常使用。当然,也不是每一个数据都要换一个行,根据自己的需要把握即可。

二、函数的参数和返回值

1、函数的传参方式

我们利用几个调用过程讲解向函数传递参数的几种方式:

  • 利用位置参数传参
    这种方式不需要写出函数的各个参数的名称,但各个参数需要按照顺序,且一一对应:
print(function(4, 1))
print(function(4))
  • 利用关键字参数传参
    这种方式需要写出各个参数的名称,各参数不需要严格按照顺序:
print(function(x = 4, y = 1))
print(function(y = 4, x = 1))
  • 利用位置参数和关键字参数相结合来传参
    这种方式中位置参数必须在前面,自从出现了第一个关键字参数后,不能再有位置参数
print(function(4, y = 1)) 

这里提出两个错误的情况:

print(function(y = 2))	 # 没有给出x的参数值
print(function(y = 2, 0))	 # 在关键字参数之后出现了位置参数

2、函数的返回值

函数可以有多个返回值,也可以仅有一个,也可以是没有返回值。我们把函数复制几份,分别根据返回值数目的不同赋予不同的名称,讲解一下设置返回值部分的规则:

def function_1return(x, y = 3):
     Dif = x - y
     Prod = x * y
     return Dif

def function_2return(x, y = 3):
     Dif = x - y
     Prod = x * y
     return Dif, Prod

def function_3return(x, y = 3):
     Dif = x - y
     Prod = x * y
     return Dif, Prod, x

def function_zeroreturn(x, y = 3):
     Dif = x - y
     Prod = x * y
     return 		# 没有返回值,但显式使用了return关键字

def function_noreturn(x, y = 3):
     Dif = x - y
     Prod = x * y	# 没有返回值,也不用return声明函数的结束

(1)带了返回值的结果,在运行时将全部返回。对于没有返回值的结果,无论带不带return语句,其函数的运行结果都是None。执行如下代码的输出结果如下:

print(function_1return(2, 3))
print(function_2return(2, 3))
print(function_3return(2, 3))
print(function_zeroreturn(2, 3))
print(function_noreturn(2, 3))

输出结果如下:

-1
(-1, 6)
(-1, 6, 2)
None
None

(2)对于有多个返回值的函数,我们可以定义与返回值数目相等的变量,去接收每一个返回值,接收返回值的过程类似于多个参数的统一赋值:

a = function_1return(2, 3)
b1, b2 = function_2return(2, 3)
c1, c2, c3 = function_3return(2, 3)
print(a)
print(b1, b2)
print(c1, c2, c3)

输出结果如下:

-1
-1 6
-1 6 2

或者,我们也可以定义一个唯一的变量接收所有这些返回值,此时被赋值的变量是一个元组形式的数据,包含了多个值。执行如下代码:

a = function_1return(2, 3)
b = function_2return(2, 3)
c = function_3return(2, 3)
print(a, b, c)

输出结果如下:

-1 (-1, 6) (-1, 6, 2)

直接定义与返回值等数目的变量接收返回值。也可以理解成把返回值的元组给自动拆包了,分给了多个变量。关于元组拆包的内容,也会在下次课提到。

三、补充知识

刚刚讲解了函数在定义、调用和返回值上的一些理论知识,在此,补充几件函数部分重要的内容:

1、函数的作用域

需要注意的是,函数体内部的变量,并不能在函数外部调用。具体示例如下:

Dif = 0
def function(x, y = 3):
     Dif = x - y
     Prod = x * y
     return Dif, Prod 

print(function(2, 3))
print(Dif)

输出结果如下:

102 [None] 3
0

从上面的例子中可以看出,Dif并没有变化,这就代表我们传递的参数不会被函数体内的操作而更改。如果需要将外部的变量引入函数中,一种做法是声明函数内的变量为全局变量。这时,我们可以引入global关键字,将函数内引用/定义的某个变量声明为全局变量。通过程序的代码和输出简单观察效果,此时作为None值的a被修改成空列表:

a = None
def bind_a_variable():
     global a
     a = []
bind_a_variable()
print(a)

输出结果如下:

[]

但是如果往函数里传入列表等数据结构的参数,在函数里修改这个参数,可能会影响原值。

2、python的函数没有重载

如果我们先后定义两个同名函数,后面的函数会直接覆盖前面的。我们试着调用之前的函数,结果会报错:例如:

def fun(x, y):
     print(3)

def fun(x):
     print(4)

输出结果如下:

fun(2, 3)	 # 报错
fun(2)

这一点请大家注意,比如不要之前定义了处理列名的函数colname,后面又定义了自己要保留的列名colname,这个列名就把函数给覆盖掉了。

3、函数的嵌套调用

这里要强调函数嵌套调用的时候,一个函数作为另一个函数的参数时,这个函数也会被执行一次。我们定义两个函数,并予以调用:

def fun1(x):
     print('fun1 called')
     return x + 4

def fun2(x, y):
     print('fun2 called')
     return x + y

x , y = 3, 4
print(fun1(fun2(x, y)))

输出结果如下:

fun2 called
fun1 called
11

fun1调用了fun2的运算结果,因此为了计算fun2的调用结果,fun2会被调用一次。再拿到fun2的运算结果(也即返回值)之后,fun1开始调用并返回结果。最后,我们把fun1的运算结果,通过print函数打印在屏幕上。

4、函数的递归调用

函数的递归调用即一个函数直接或间接调用自身的过程,看如下的例子:

def fun_recur(x, t):
     if x > 1:
         x -= 1
         t += 10
         return fun_recur(x, t)
     else:
         return t

fun_recur(3.2, 25)

输出结果如下:

55

上述例子产出最终的结果55,实际上包含了如下的过程:

x = 3.2,t自加10,进入一重递归
x = 2.2,t自加10
x = 1.2,t自加10
x = 0.2,进入else语句,返回值为t(55),之后先后跳出之前的三次递归过程,返回结果。

递归函数在将一个大问题能转化成反复调用的小问题时,很省代码量,但是递归本身的效率相比普通循环要低,因此在使用的时候建议有所取舍。

5、函数作为函数调用的参数,作为值传递的参数

在python中,所有的元素都是对象,函数也能作为函数本身调用的对象和值传递的参数,例如如下的代码块,利用函数作为参数传递的方式,实现当x满足某个条件时,返回x+y,而这个条件通过函数对象funx进行描述:

def fun(x, y, funx):
    if funx(x) < 0:
        return x
    else:
        return x + y
    
def funx(x):
     return x - 50

print(fun(40, 30, funx))
print(fun(80, 30, funx))

输出结果如下:

40
110

一个函数就像各种其他参数一样,也能作为函数的参数,请注意它的启发性。

四、函数举例

1、格式转换函数

它传入一个参数,即将一个类型的数值转换为另一个类型。我们最常用的就是整型、浮点型和字符串的互转,我们只需要将待转格式的参数传入相应的函数即可:

int()函数能将浮点型或可以看做整数的数据转成整数,是截断,即删去小数位。
float()函数能将整或可以看做数值型(整数小数均可)的数据转成浮点数。
str()函数能将各类数字转成对应的字符串。
print(int(3.5))
print(int('10'))
print(float(4)) 
print(float('3.5'))
print(str(1.2) + 'test') 	# 只有字符串能通过加号拼接其他字符串,表明转换成功

输出结果如下:

3
10
4.0
3.5
1.2test

2、range()函数

range函数的语法:

range(start, stop[, step])

  • start:表示初始值
  • stop:终止值(不包括)
  • step:步长

它有三种传参使用的情况:

  • 传入三个参数:分别传入起始值、终止值和步长。它会返回一个range对象,我们需要用list函数把它转换成列表来查看它的值,具体示例如下:
print(range(2, 20, 4))
print(list(range(2, 20, 4)))

输出结果如下:

range(2, 20, 4)
[2, 6, 10, 14, 18]

当步长为负值时:

print(list(range(10, 1, -2)))

输出结果如下:

[10, 8, 6, 4, 2]

这里来看两种比较特殊的情况,第一种是,步长已经超过了整个start-stop的跨度,此时返回的range转成列表后只有start一个元素:

print(list(range(1, 10, 100)))

输出结果如下:

[1]

第二种是,步长和start-stop变化的方向彻底相反(相当于定义错了),此时返回的range转成列表后是空列表:

print(list(range(1, 10, -2)))

输出结果如下:

[]
  • 传入两个参数:即startstop,此时step取默认值1:
print(list(range(2, 5)))

输出结果如下:

[2, 3, 4]
  • 传入一个参数:只传递一个参数stop,此时默认值start = 0step = 1
print(list(range(5)))

输出结果如下:

[0, 1, 2, 3, 4]

在之后的数据分析任务中,会经常使用for循环并结合range函数这种方式来访问各种数组、列表、数据框等数据结构中的元素值,以列表为例:

listtmp = ['12', '23', '34', '45', '56']
for i in range(len(listtmp)):
     print(listtmp[i])

输出结果如下:

12
23
34
45
56

补充一点,内置的range函数传递的参数必须是整数,否则会报错。

3、print()函数

print函数在这里细讲的原因它可以输出我们能接触到的几乎所有对象,我们只讲输出一般的数值,以及将之整理成格式化字符串结果的那种功能。

(1) 它可以接收多个待输出的值,不同参数类型可以不一样,参数之间用逗号分隔(两个逗号之间不能没有值),这是它的基础用法:

print('alpha', 1, 'beta', 2, ['listvalue1', 'listvalue2', 2.5])

输出结果如下:

alpha 1 beta 2 ['listvalue1', 'listvalue2', 2.5]

(2)关于它的两个参数:一个是输出参数之间的分隔符sep,默认参数是’ ',即一个空格,我们可以改成自己愿意的值,当然必须是空或者是字符串。具体代码及输出结果如下:

a = 10
print('alpha', 1, 'beta', 2, ['listvalue1', 'listvalue2', 2.5], sep = ' _%_ ')
print('alpha', 1, 'beta', 2, ['listvalue1', 'listvalue2', 2.5], sep = a) 	# 报错1,sep错误
alpha _%_ 1 _%_ beta _%_ 2 _%_ ['listvalue1', 'listvalue2', 2.5]
报错1【TypeError: sep must be None or a string, not list

第二个参数是在整个输出末尾的符号end,默认是换行符’\n’,这么做表示在默认参数下,每次输出都自动换行,我们可以把end改成自己需要的标识符,此时便不换行。当我们连续调用两个print,将第一个print的结尾换成一个字符串后,再输出下一句话时就不会换行了,如代码运行的结果所示。当然,输出if newline这句话后是会换行的,因为end是默认值’\n’:

print('alpha', 1, 'beta', 2, ['listvalue1', 'listvalue2', 2.5], end = ' _end_ ')
print('if newline ?')

输出结果如下:

alpha 1 beta 2 ['listvalue1', 'listvalue2', 2.5] _end_ if newline ? 

对于缺乏Python基础的同仁,可以通过免费专栏🔥《Python学习笔记(基础)》从零开始学习Python

结语

请始终相信“Done is better than perfect” ,不要过分追求完美,即刻行动就是最好的开始, 一个模块一个模块地积累和练习,必将有所收获。
还有其他的问题欢迎在评论区留言📝!


[版权申明] 非商业目的注明出处可自由转载,转载请标明出处!!!
博客:butterfly_701c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值