跳转至

初学函数

什么是函数


点击这里,边看视频讲解,边学习以下内容

人类语言里面,我们不仅会给人和物起名字, 比如 小张, 足球, iphone

有时候,我们还要给 一件事情,一串动作起名字,指代 某个流程。

比如:我们公司的面试流程是

把求职者带到3号会议室
请求职者 完成答卷
让测试经理来面试 求职者
让技术总监面试 求职者

我们会把上面这 一连串的事情,起名叫 面试流程

面试流程就代表了这一串动作。

以后,我们想告诉 HR 给谁面试的时候,只要说,走面试流程 ,就行了。

不需要说, HR ,请你做如下的事情

把求职者带到3号会议室
请求职者 完成答卷
让测试经理来面试 求职者
让技术总监面试 求职者

你们会这么说吗?

不会,因为这样太麻烦了。我给它起名字面试流程,只要说 :“走面试流程”,HR 自然知道是什么意思。这样就方便多了。


同样的道理,在编程上,如果我要多次输出面试的流程,就像下面的代码,

print("把求职者带到3号会议室")
print("请求职者 完成答卷")
print("让测试经理来面试 求职者")
print("让技术总监面试 求职者")

每次都全部写一遍太烦了, 就可以定义一个名字来代表要执行这四条语句

定义一个名字 对应多个语句操作, 称之为定义函数

所以:定义函数 就好像是给 一段代码 起了个名字

Python中,我们是这样定义函数的:

def interview():
    print("把求职者带到3号会议室")
    print("请求职者 完成答卷")
    print("让测试经理来面试 求职者")
    print("让技术总监面试 求职者")

def 是关键字 表示定义一个函数

后面是函数的名字,紧接着后面需要一个括号 ,这个括号中间,根据需要还可以有 参数,这里我们先不讲它

最后是一个冒号,下面的缩进的代码表示这个函数名字代表的具体动作是什么,称之为函数体

函数体的代码是需要缩进的。我们建议缩进四个空格。

这样定义好了以后,后面的代码要指代这个面试的流程,只需要写名字 interview 就行了。 比如:

print(interview)
运行一下,发现会输出内容如下
<function interview at 0x05292468>

表示这个 interview 是 一个函数类型的对象。

特别要注意的是,解释器执行到 定义函数 的语句时,并不会执行函数体里面的代码。

要执行函数体里面的代码,必须 调用函数

Python代码怎么调用函数呢?就是在 函数名后面加上括号。

比如,要执行 interview 这个名字代表的动作,就在后面加上括号 interview()

如下:

interview()
print('后续代码')

interview() 就叫 调用函数 interview ,有时也叫做 执行函数 interview。

当解释器 执行到 这行调用函数的代码时,就会跑到 函数 interview 里面,去执行函数里面的语句。

函数必须先定义,后面才能调用。


调用后返回

注意,当解释器执行完被调用函数内部的代码后,还会 返回 到调用它的代码处,继续执行后面的代码。

上面的例子里面, 执行完 interview 对应的函数内部代码后, 会返回调用处,执行后面的 这条语句

print('后续代码')

内置函数

大家仔细看看我们的代码, 里面除了有 interview 这个函数,还有什么函数?

对了,print

其实,我们这里 print 这个名字 也是一个函数的名字, 表示一个动作就是把里面的对象 显示到屏幕上

这个动作实现的具体代码在哪里?

python语言的开发者 知道 这是我们常用的操作, 所以在python解释器内部已经帮我们实现好了 这样一个函数, 称之为内置函数。

函数的参数


点击这里,边看视频讲解,边学习以下内容

这个print函数调用的时候,有个和我们上面定义的 interview 有明显的不同,大家有没有发现?

看看

interview()
print("把求职者带到3号会议室")
区别在哪里? 对了,括号里面有内容。

函数调用括号里面的内容 称之为函数的 参数

有的函数要完成功能,需要告诉它一些信息。

比如print函数,如果你不告诉它要打印的内容是什么,它怎么能打印信息到屏幕上呢?

参数的作用 就是: 提供 函数完成功能 所必须的信息


有参数的函数像这样

def func(para1,para2):
    ...

函数的参数都是放在函数定义的括号里面的。

比如上面示例代码中的 para1,para2

参数其实也是一个变量,所以他们的命名规则和变量的命名规则一样。

参数可以没有,可以是一个,也可以是多个。参数之间用逗号隔开。

调用有参数的函数时,需要传入对应个数的参数。

是一个参数,就传入一个,两个就是传入两个

我们上面interview的例子里面,如果我们要加上显示出面试者的名字,就可以这样

def interview(interviewee):
    print("求职者是 " + interviewee)
    print("把求职者带到3号会议室")
    print("请求职者 完成答卷")
    print("让测试经理来面试 求职者")
    print("让技术总监面试 求职者")

interview('王小五')

我们在定义的时候,并不知道将来调用的时候是谁来面试。

但是没有关系。可以作为参数,定义在这里。

面试者来了,我们在调用函数的时候,会将面试者的名字作为参数传递过来。

在执行

interview('王小五')

的时候, 解释器就会到 函数 interview 准备去执行里面的代码,并且在执行函数代码前,会将参数变量 interviewee 赋值为 '王小五'


函数的返回值

什么是函数返回值

点击这里,边看视频讲解,边学习以下内容

有的函数执行一个流程就完了,并不需要返回什么信息,比如 print 函数,就是打印一下参数字符串,就完成了它的任务。

但是有的函数,需要返回一个结果给调用者。

比如 计算两个数字平方和的函数,必须要返回一个结果,告诉调用代码,平方和的计算结果。

函数要返回结果,就必须要使用 return 关键字,后面加上返回的结果对象

比如:

def squarep(num1,num2):
    return num1**2 + num2**2

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

语句ret = squarep(1,2) 等号右边的 就是函数调用的表达式。

解释器在执行这条语句的时候,会执行squarep函数对应的代码,函数代码最后返回一个平方和的计算结果。

这个计算结果(是一个数字对象) 就被赋值给了变量 ret

所以接下来的语句print(ret),就可以打印出1 和 2 的平方和 计算结果 5


解释器执行代码的时候,一旦执行了函数中的 return 语句,就会立即从函数中返回到调用的地方,该函数下面还有代码,也不会再执行了。

比如

def squarep(num1,num2):
    return num1**2 + num2**2
    print('这条语句在return后面,不会执行')

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


如果一个函数定义,里面并没有写return语句,像这样

def func1():
    print('你好')

print(func1())    

那么该函数调用后会返回一个None对象。 None对象是Python内置的,表示没有数据内容的对象。


print的内容不是返回值

白月黑羽 零基础的小班学员, 经常傻傻分不清下面这两段代码有什么区别

def squarep(num1,num2):
    ret = num1**2 + num2**2
    print(ret)

ret = squarep(1,2)


def squarep(num1,num2):
    ret = num1**2 + num2**2
    return ret

ret = squarep(1,2)


他们会这样告诉我: 第1段代码运行后打印出了结果,所以函数 squarep 有返回值,而第2段代码运行后没有打印结果所以squarep没有返回值。

天哪,至少有5个小班学员有这样的误解了。

再次强调,之所以你在屏幕上能看到打印结果,是因为代码里面有print语句的原因,不是因为有返回值。

返回值要能显示在屏幕上也必须调用print打印出来。

像这样

def squarep(num1,num2):
    ret = num1**2 + num2**2
    return ret

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

上面第1段代码,由于没有写return语句,所以返回的是None(空对象)而不是计算结果,它只是打印了计算结果。

而第2段代码才是返回了计算平方和的结果。

可以点击这里,学习一下视频讲解


缺省值参数


点击这里,边看视频讲解,边学习以下内容

假设,我们要实现一个函数,统计考试得分超过指定分数的人数。

def  overScoreStudents(studentScoreList, score):
    count = 0

    # 下面的代码用到了循环和判断,后面章节会学习到
    for ss in studentScoreList:
        if ss >= score:
            count += 1

    return count

在调用这个函数的时候,大部分时候 都是统计超过及格分数线60的人数。像这样

overScoreStudents(ssList,60)

所以,我们调用该函数的时候,第二个参数通常都是填写 60 。

这样显得就有些麻烦。

这时候,可以在定义函数的时候,给它加上缺省值,像下面这样:

def  overScoreStudents(studentScoreList, score=60):
    ...

这样,在调用这个函数的时候,如果score参数还是传入60 就可以不用写了,像这样

overScoreStudents(ssList)

解释器发现该函数参数score有缺省值,就会自动帮我们传入缺省值60 给 参数score。

当然如果我们调用的时候传入了参数,比如像下面这样,解释器就会将 70 传给参数score。

overScoreStudents(ssList, 70)


函数的参数定义,一旦有缺省值后,后面所有的参数必须都有缺省值

下面这样的定义是错误的

def  func(arg1, arg2, arg3=3, arg4):
    ...

arg4 前面的参数 arg3 已经有缺省值,所以必须也要有缺省值,比如

def  func(arg1, arg2, arg3=3, arg4='hello'):
    ...


如果你对函数的缺省值的作用 仍然不太理解,请点击这里,观看看白月黑羽和实战班学员的1对1讲解答疑视频


指定参数名调用函数

这样的一个函数

def  func(arg1, arg2, arg3=3, arg4='hello'):
    print(arg1)
    print(arg2)
    print(arg3)
    print(arg4)

我们调用的时候,可以这样

func(1,2,3,'hello')

也可以这样 指定参数名 去调用

func(arg1=1,arg2=2,arg3=3,arg4='hello')


指定参数名调用的时候,可以颠倒参数的次序

func(arg2=1,arg3=2,arg1=3,arg4='hello')


也可以这样混合使用

func( 1, 2, arg3=3,arg4='hello')

但是一旦某个参数指定了参数名,后面所有的参数必须指定参数名

像下面这样是不可以的

func( 1, 2, arg3=3, 'hello') # 错误的调用方式


变量的有效范围

点击这里,边看白月黑羽和实战班学员的1对1讲解视频,边学习下面的内容

局部变量

大家来看这样一个例子

def func(num1,num2):
    ret = num1 + num2
    return ret

func(1,2)
print(ret)    

运行程序,可以发现 这样的错误提示

Traceback (most recent call last):
  File "sample.py", line 6, in <module>
    print(ret)
NameError: name 'ret' is not defined

定义在某个函数内部的变量,称之为 局部变量

函数的参数变量 也是 局部变量。

局部变量有效范围只能是该函数内部。

因为 ret 是 func 函数内部的 局部变量 , 有效范围只能是 func函数内部, 不能在外部使用。

同样的,参数变量, 比如上面的 num1, num2 也是函数 内部的局部变量,这两个变量名也只能在 func函数内部使用。


全局变量

大家再来看这样一个例子

# 获取数字对应的汉字
upChars = '零壹贰叁肆伍陆柒捌玖'
def getZh(num):
    print('对应的汉字是:' + upChars[num])

getZh(5) 

定义在所有函数外部的变量,称之为 全局变量

全局变量的有效范围是整个模块文件。

上面的例子中 upChars 就是一个 全局变量。

函数内部代码 可以访问 全局变量的。

范围覆盖

大家再来看这样一个例子

upChars = '零壹贰叁肆伍陆柒捌玖'
def getZh(num):
    upChars = '零一二三四五六七八九'
    print('对应的汉字是:' + upChars[num])

getZh(5) 

在函数内部,如果 局部变量 和 全局变量同名,使用的是 局部变量。


如果在函数内部要对全局变量进行重新赋值,不能直接这样

upChars = '零壹贰叁肆伍陆柒捌玖'
def change():
    upChars = '零一二三四五六七八九'

change()
print(upChars)

因为,解释器会认为函数内部 是重新定义了一个局部变量, 而不是把全局变量进行重新赋值。

应该这样做

upChars = '零壹贰叁肆伍陆柒捌玖'
def change():
    global upChars
    upChars = '零一二三四五六七八九'

change()
print(upChars)

通过 global upChars 这行声明,表示 upChars 这个名字对应的是全局变量 upChars

常用 内置函数

我们通常会把常用的代码放到函数里面,这样要使用这些代码 ,只需要调用那些函数就可以了。

Python的设计者 为我们总结了一些常用的函数,放到了Python解释器中,这些函数我们直接就可以使用。

前面我们学过的print 就是其中之一。

内置函数可以在Python的官方文档查看到,点击这里查看官方文档,。

abs()   dict()  help()  min()   setattr()
all()   dir()   hex()   next()  slice()
any()   divmod()    id()    object()    sorted()
ascii() enumerate() input() oct()   staticmethod()
bin()   eval()  int()   open()  str()
bool()  exec()  isinstance()    ord()   sum()
bytearray() filter()    issubclass()    pow()   super()
bytes() float() iter()  print() tuple()
callable()  format()    len()   property()  type()
chr()   frozenset() list()  range() vars()
classmethod()   getattr()   locals()    repr()  zip()
compile()   globals()   map()   reversed()  __import__()
complex()   hasattr()   max()   round()  
delattr()   hash()  memoryview()    set()    

我们先了解其中常用的几个

int

int 函数 经常被我们用来把一个字符串转化为对应的整数

比如

int('1000')   # 返回整数1000

也经常用来把一个小数转化为对应的整数,去掉其中的小数部分

比如

int(3456.23)  # 返回整数3456

float

float 函数 用来把一个字符串转化为对应的小数(浮点数)

比如

float('1000')    # 返回 浮点数 1000.0
float('6.345')   # 返回 浮点数 6.345

也可以把一个整数对象转化为对应的小数对象

比如

float(1000)  # 返回浮点数 1000.0

str

str 函数 用来得到一个对象的字符串表示。

经常被我们用来把数字转化为对应的字符串表示的数字

比如

str(1000)   # 返回字符串 '1000'
str(1000.23)   # 返回字符串 '1000.23'

len

len 函数 可以得到一个数据对象的长度,通常用来获取 字符串、列表、元组、字典等类型对象的元素个数。

比如

print (len('你好!'))
可以得到字符串的长度 3

type

type 函数 可以得到一个数据对象类型

比如

type(3)        # 返回  <class 'int'>

type('hello')  # 返回  <class 'str'>

您需要高效学习,找工作? 点击咨询 报名实战班

点击查看学员就业情况


课后练习

去做练习