Python零基础入门篇 - 31 - 函数的定义与使用,超详细

需要注意的是,return 只能在函数体内使用; return 支持返回所有的数据类型,当一个函数返回之后,我们可以給这个返回值赋予一个新的变量来使用。

由此我们总结出:

  • return 是将函数结果返回的关键字

  • return 只能在函数体内使用

  • return 支持返回所有的数据类型

  • 有返回值的函数,可以直接赋值给一个变量

return 的用法,示例如下:

def add(a,b):

c = a + b

return c

#函数赋值给变量

result = add(a=1,b=1)

print(result)

#函数返回值作为其他函数的实际参数

print(add(3,4))

需要注意的是,return 语句在同一函数中可以出现多次,但只要有一个得到执行,就会直接结束函数的执行。

现在我们利用 return 关键字 ,尝试自定义一个 capitalize 函数。示例如下:

def capitalize(data):

index = 0

temp = ‘’

for item in data:

if index == 0:

temp = item.upper()

else:

temp += item

index += 1

return temp

result = capitalize(‘hello , Jack’)

print(result)

>>> 执行结果如下

>>> Hello , Jack



再一次注意到,只要有一个得到执行,就会直接结束函数的执行。

return 与 print 的区别

  • print 只是单纯的将对象打印输出,并不支持赋值语句。

  • return 是对函数执行结果的返回,且支持赋值语句;但是我们可以将含有 renturn 值的函数放在 print 里进行打印。

函数的传参


  • 必传参数:平时最常用的,必传确定数量的参数

  • 默认参数:在调用函数时可以传也可以不传,如果不传将使用默认值

  • 不确定参数:可变长度参数(也叫可变参数)

  • 关键字参数:长度可变,但是需要以 key-value 形式传参

必传参数

什么是必传参数? —> 在定义函数的时候,没有默认值且必须在函数执行的时候传递进去的参数;且顺序与参数顺序相同,这就是必传参数。

  • 函数中定义的参数没有默认值,在调用函数的时候,如果不传入参数,则会报错。

  • 在定义函数的时候,参数后边没有等号与默认值。

  • 错误的函数传参方式:def add(a=1, b=1)

错误示例如下:

def add(a, b):

return a + b

result = add()

print(result)

>>> 执行结果如下

>>> TypeError: add() missing 2 required positional arguments: ‘a’ and ‘b’

正确的示例如下:

def add(a, b):

return a + b

result = add(1, 2)

print(result)

>>> 执行结果如下

>>> 3

>>> add 函数有两个参数,第一个参数是 a,第二个参数是 b

>>> 传入的两个整数按照位置顺序依次赋给函数的参数 a 和 b,参数 a 和参数 b 被称为位置参数

传递的参数个数必须等于参数列表的数量

  • 根据函数定义的参数位置来传递参数,要求传递的参数与函数定义的参数两者一一对应

  • 如果 “传递的参数个数” 不等于 “函数定义的参数个数”,运行时会报错

错误传参数量示例如下:

def add(a, b):

return a + b

sum = add(1, 2, 3)

>>> 执行结果如下

>>> sum = add(1, 2, 3)

>>> TypeError: add() takes 2 positional arguments but 3 were given

默认参数

  • 在定义函数的时候,定义的参数含有默认值,通过赋值语句给参数一个默认的值。

  • 使用默认参数,可以简化函数的调用,尤其是在函数需要被频繁调用的情况下

  • 如果默认参数在调用函数的时候被给予了新的值,函数将优先使用新传入的值进行工作

示例如下:

def add(a, b, c=3):

return a + b + c

result = add(1, 2) # 1 对应的 a ;2 对应的 b ; 没有传入 C 的值,使用 C 的默认值 3。

print(result)

>>> 执行结果如下

>>> 6

def add(a, b, c=3):

return a + b + c

result = add(1, 2, 7) # 1 对应的 a ;2 对应的 b ; 传入 C 的值为 7,未使用 C 的默认值 3。

print(result)

>>> 执行结果如下

>>> 10

不确定参数(可变参数)

  • 这种参数没有固定的参数名和数量(不知道要传的参数名具体是什么)

不确定参数格式如下:

def add(*args, **kwargs):

pass

*args :将无参数的值合并成元组

**kwargs :将有参数与默认值的赋值语句合并成字典

  • *args 代表:将无参数的值合并成元组

  • **kwargs 代表:将有参数与默认值的赋值语句合并成字典

从定义与概念上似乎难以理解,现在我们通过示例来看一下:

def test_args(*args, **kwargs):

print(args, type(args))

print(kwargs, type(kwargs))

test_args(1, 2, 3, name=‘Neo’, age=18)

>>> 执行结果如下

>>> (1, 2, 3) <class ‘tuple’>

>>> {‘name’: ‘Neo’, ‘age’: 18} <class ‘dict’>

>>> args 将输入的参数转成了一个元组

>>> kwargs 将输入的赋值语句转成了一个字典

>>> 在使用的时候,我们还可以根据元组与字典的特性,对这些参数进行使用;示例如下:

def test_args(*args, **kwargs):

if len(args) >= 1:

print(args[2])

if ‘name’ in kwargs:

print(kwargs[‘name’])

test_args(1, 2, 3, name=‘Neo’, age=18)

>>> 执行结果如下

>>> 3 根据元组特性,打印输出 args 索引为 2 的值

>>> Neo 根据字典特性,打印输出 kwargs 的 key 为 name 的 value

def test_args(*args, **kwargs):

if len(args) >= 1:

print(args[2])

else:

print(‘当前 args 的长度小于1’)

if ‘name’ in kwargs:

print(kwargs[‘name’])

else:

print(‘当前 kwargs 没有 key为 name 的元素’)

test_args(1, 2, 3, name1=‘Neo’, age=18)

>>> 执行结果如下

>>> 3 根据元组特性,打印输出 args 索引为 2 的值3

>>> 当前 kwargs 没有 key为 name 的元素(传入的 kwargs 为 name1=‘Neo’, age=18;没有 name)

参数规则

def add(a, b=1, *args, **kwargs)

  • 参数的定义从左到右依次是 a - 必传参数b - 默认参数可变的 *args 参数可变的 **kwargs 参数

  • 函数的参数传递非常有灵活性

  • 必传参数与默认参数的传参也非常具有多样化

示例如下:

def add(a, b=2):

print(a + b)

我们来看一下该函数可以通过哪些方式传递参数来执行

add(1, 2) # 执行结果为 : 3

add(1) # 执行结果为 : 3

add(a=1, b=2) # 执行结果为 : 3

add(a=1) # 执行结果为 : 3

add(b=2, a=1) # 执行结果为 : 3

add(b=2)

执行结果为 : TypeError: add() missing 1 required positional argument: ‘a’ 。

(因为 a 是必传参数,这里只传入 b 的参数是不行的)

def test(a, b, *args):

print(a, b, args)

int_tuple = (1, 2)

test(1, 2, *int_tuple)

>>> 执行结果如下

>>> 1 2 (1, 2)

***********************************************************

def test(a, b, *args):

print(a, b, args)

int_tuple = (1, 2)

test(a=1, b=2, *int_tuple)

>>> 执行结果如下

>>> TypeError: test() got multiple values for argument ‘a’

>>> 提示我们参数重复,这是因为 必传参数、默认参数、可变参数在一起时。如果需要赋值进行传参,需要将可变参数放在第一位,然后才是 必传参数、默认参数。(这是一个特例)

************************************************************

def test(*args, a, b):

print(a, b, args)

int_tuple = (1, 2)

test(a=1, b=2, *int_tuple)

>>> 执行结果如下

>>> 1 2 (1, 2)

>>> 这种改变 必传参数、默认参数、可变参数 的方式,一般我们是不推荐使用的

def test(a, b=1, **kwargs):

print(a, b, kwargs)

test(1, 2, name=‘Neo’)

test(a=1, b=2, name=‘Jack’)

test(name=‘Jack’, age=18, a=1, b=2)

>>> 执行结果如下

>>> 1 2 {‘name’: ‘Neo’}

>>> 1 2 {‘name’: ‘Jack’}

>>> 1 2 {‘name’: ‘Jack’, ‘age’: 18}

注意:如果传参的顺序发生变化,一定要使用赋值语句进行传参。

函数小练习


需求:定义一个 login 函数,向函数内传入形参 username,password,当 username 值为 admin 且password值为字符串 123456 时,返回“登录成功”;否则返回“请重新登录”

def login(username, password):

定义一个登录函数,传入 username, password 必填参数

if username == “admin” and password == “123456”:

使用if语句,判断用户名和密码为“admin”和“123456”

print(“登录成功”) # 返回登录成功

else:

使用else子句处理用户名和密码非“admin”和“123456”的情况

print(“请重新登录”) # 返回请重新登录

调用函数,向函数内传入’admin’,‘123456’和’test’,'123456’两组数据测试结果

login(username=“admin”, password=“123456”) # 打印函数测试结果

login(username=“test”, password=“123456”) # 打印函数测试结果

函数的参数类型定义


前文我们学习了函数的定义方法与使用方法,在定义参数的时候我们并不知道参数对应的数据类型是什么。都是通过函数体内根据业务调用场景去判断的,如果传入的类型与也无偿性不符,就会产生报错。现在我们学习一种方法,可以在定义函数的时候,将参数类型与参数一同定义,方便我们知道每一个参数需要传入的数据类型。

我们来看一个例子:

def person(name:str, age:int=18):

print(name, age)

  • 必传参数:参数名 + 冒号 + 数据类型函数 ,为声明必传参数的数据类型

  • 默认参数:参数名 + 冒号 + 数据类型函数 + 等号 + 默认值,为声明默认参数的数据类型

  • 需要注意的是,对函数的定义数据类型在 python 3.7 之后的版本才有这个功能

  • 虽然我们给函数参数定义了数据类型,但是在函数执行的时候仍然不会对参数类型进行校验,依然是通过函数体内根据业务调用场景去判断的。这个定义方法只是单纯的肉眼上的查看。

示例如下:

def add(a: int, b: int = 3):

print(a + b)

add(1, 2)

add(‘Hello’, ‘World’)

>>> 执行结果如下:

>>> 3

>>> HelloWorld

def add(a: int, b: int = 3, *args:int, **kwargs:str):

print(a, b, args, kwargs)

add(1, 2, 3, ‘4’, name=‘Neo’)

>>> 执行结果如下:

>>> 1 2 (3, ‘4’) {‘name’: ‘Neo’}

我们发现执行的函数并没有报错,add(‘Hello’, ‘World’) 也通过累加的方式拼接在了一起

所以说,虽然我们定义了 int 类型,但是并没有做校验,只是单纯的通过肉眼告知我们参数是 int 类型,后续我们进入python高级进阶阶段可以自己编写代码进行校验。

全局变量与局部变量


  • 全局变量:在当前 py 文件都生效的变量

  • 在 python 脚本最上层代码块的变量

  • 全局变量可以在函数内被读取使用

  • 局部变量:在函数内部,类内部,lamda.的变量,它的作用域仅在函数、类、lamda 里面

  • 在函数体内定义的变量

  • 局部变量无法在自身函数以外使用

全局变量

示例如下:

coding:utf-8

name = ‘Neo’

age = 18

def test01():

print(name)

def test02():

print(age)

def test03():

print(name, age)

test01()

test02()

test03()

>>> 执行结果如下:

>>> Neo

>>> 18

>>> Neo 18

>>> 这里我们可以看到声明的 全局变量 在多个函数体内都可以被使用

局部变量

示例如下:

coding:utf-8

name = ‘Neo’

age = 18

def test01():

name = ‘Jack’

age = 17

print(‘这是函数体内的局部变量’, name, age)

test01()

print(‘这是函数体外的全局变量’, name, age)

>>> 执行结果如下:

>>> 这是函数体内的局部变量 Jack 17

>>> 这是函数体外的全局变量 Neo 18

>>> 这里我们既声明声明了全局变量,同时还在函数体内变更了变量的值使其成为了局部变量。

>>> 同时,根据打印输出的结果我们可以看出局部变量仅仅作用于函数体内。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Python工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Python开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Python开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注Python)
img

最后

🍅 硬核资料:关注即可领取PPT模板、简历模板、行业经典书籍PDF。
🍅 技术互助:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。
🍅 面试题库:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。
🍅 知识体系:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。

助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-cia50qzm-1711801939540)]
[外链图片转存中…(img-W1ga3Gji-1711801939541)]



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Python开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024c (备注Python)
[外链图片转存中…(img-9KQHdcO1-1711801939542)]

最后

🍅 硬核资料:关注即可领取PPT模板、简历模板、行业经典书籍PDF。
🍅 技术互助:技术群大佬指点迷津,你的问题可能不是问题,求资源在群里喊一声。
🍅 面试题库:由技术群里的小伙伴们共同投稿,热乎的大厂面试真题,持续更新中。
🍅 知识体系:含编程语言、算法、大数据生态圈组件(Mysql、Hive、Spark、Flink)、数据仓库、Python、前端等等。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值