当前位置: 首页 > news >正文

Python编程基础:函数的使用

Python编程基础:函数的使用

文章目录

  • Python编程基础:函数的使用
    • 一、前言
    • 二、我的环境
    • 三、函数的定义与调用
    • 四、传递实参
      • 1、位置实参
      • 2、关键字实参
      • 3、默认值
      • 4、可变长度参数
      • 5、避免实参错误
    • 五、返回值
      • 1、返回简单值
      • 2、让实参变成可选的
      • 3、返回字典
    • 六、传递列表
    • 七、变量作用域
    • 八、匿名函数
    • 九、最后我想说

一、前言

紧跟学校课程安排,目前我们正在学习有关Python函数的相关知识,所以我就来对Python函数的使用进行一个简单的总结,后续老师会布置对应的实验,我也会第一时间的更新实验内容的。

函数这一章内容比较重要,后续会经常用到,也是常考点,需要大家认真学习并练习。

二、我的环境

  • 电脑系统:Windows 11
  • 语言版本:Python 3.10.4
  • 编译器:VSCode

三、函数的定义与调用

简单来说函数是一段具名的、实现特定功能的、可重用的代码段,函数提供了一种进行巩固抽象和代码重用的手段,在Python中函数定义一般形式如下:

def 函数名(形参列表):
    """函数文档字符串"""
    函数体
    [return [返回值]]

例如,我们定义一个简单函数来进行说明一下:

def fact(n):
    """计算n的阶乘。"""
    k = 1
    for i in range(2, n+1):
        k *= i
    return k
print(fact(5))
print(fact.__doc__)

它运行的结果是:

120
计算n的阶乘。

这里,def关键字是Python中定义函数的开始,在一个项目中国函数名必须唯一,如果出现同名就会被覆盖但不会被报错,圆括号及其后的冒号必须要有,内部的形式参数可以有多个但要用逗号隔开,也可以不填入参数。

函数如果有参数或者返回值的话,它们的数据类型都不用声明,因为Python是一种动态语言,可自动识别对象类型。

函数文档字符串需要使用一对三个单引号或者三个双引号包围,允许对函数巩固、参数等进行说明,可以省略但最好写养成良好习惯,我们可以调用__doc__方法查看。

最后我们可以使用return语句返回一个或多个值,也可以只有return关键字而没有返回值,还可以没有return语句,函数在执行return语句之后就会直接退出函数执行,所以在return语句之后的语句将不会被执行。

四、传递实参

Python参数传递的方式是传递对象的引用(即对象的内存地址),而不是传递对象的值。

1、位置实参

调用函数时,Python必须将函数调用中的每个实参都关联到函数定义中的一个形参,最简单的关联方式是基于实参的顺序,这种关联方式称为位置实参。

举个例子:

def describe_pet(animal_type, pet_name):
    """显示宠物信息。"""
    print("我有一个{}。".format(animal_type))
    print("我的{}名字是{}。".format(animal_type, pet_name.title()))
describe_pet("仓鼠", "杰瑞")

它运行的结果是:

我有一个仓鼠。
我的仓鼠名字是杰瑞。

需要注意的是位置实参的顺序很重要,如果顺序错误,输出的结果就会不对应。

2、关键字实参

关键字实参是传递给函数的名称值对,因为直接在实参中将名称和值关联起来,所以向函数传递实参时不会混淆,关键字实参让你无须考虑函数调用中的实参顺序,还清楚地指出了函数调用中各个值的用途。

还是上面那个例子我们稍微改一下:

def describe_pet(animal_type, pet_name):
    """显示宠物信息。"""
    print("我有一个{}。".format(animal_type))
    print("我的{}名字是{}。".format(animal_type, pet_name.title()))
describe_pet(animal_type="仓鼠", pet_name="杰瑞")

我们指定实参值之后就不会出现顺序错误导致输出错误了。

3、默认值

我们在编写函数的时候可以给形参赋默认值,如果我们没有为它赋予实参则它将默认使用默认值。

我们继续将上面那个例子进行修改:

def describe_pet(animal_type="仓鼠", pet_name):
    """显示宠物信息。"""
    print("我有一个{}。".format(animal_type))
    print("我的{}名字是{}。".format(animal_type, pet_name.title()))
describe_pet(pet_name="杰瑞")

这里我们最后只传入了一个实参,但输出结果跟上面的一样就是因为我们设置了默认值。

4、可变长度参数

可变长度参数是指一个形参能够接收的实参数是可变的,它有两种形式:

  • 形参前加一个*号,表示可以接收多个位置参数并把他们放到一个元组中

    def demo1(*args):
        print(args)
    demo1(1, 2, 3, 4, 5, 6)		# 结果为(1, 2, 3, 4, 5, 6)
    
  • 形参前加两个**号,表示可以接收多个关键字参数并把它们放到一个字典中

    def demo2(**kwargs):
        print(kwargs)
    demo2(x = 1, y = 2, z = 3)		# 结果为{'x': 1, 'y': 2, 'z': 3}
    

5、避免实参错误

我们需要注意的是我们定义了多少实参最后就需要传入多少个,如果传入的实参与函数的不匹配就会出现报错,这一点我们需要注意。

五、返回值

函数并非总是直接显示输出,它还可以处理一些数据,并返回一个或一组值,函数返回的值称为返回值,它可以将程序的大部分繁琐的工作放到函数内去完成,从而简化主程序。

1、返回简单值

例如返回姓名:

def get_formatted_name(first_name, last_name):
    """返回姓名"""
    full_name = f"{first_name} {last_name}"
    return full_name.title()

musician = get_formatted_name("jimi", "hendrix")
print(musician)

它运行的结果是:

Jimi Hendrix

2、让实参变成可选的

有些时候我们需要将实参变成可选的,这里我们就会用到前面所讲的默认值。

例如,假如我们要给前面定义的函数添加处理中间名的功能:

def get_formatted_name(first_name, middle_name, last_name):
    """返回姓名"""
    full_name = f"{first_name} {middle_name} {last_name}"
    return full_name.title()

musician = get_formatted_name("john", "lee", "hooker")
print(musician)

它运行的结果是:

John Lee Hooker

但是并不是所有人都有中间名,所以现在我们需要做的就是将中间名这个参数变成可选的,那就是给它赋予默认值,且默认值为空字符串,如果传入该参数就使用实参,没有传入就使用默认值空字符串代替:

def get_formatted_name(first_name, last_name, middle_name=''):
    """返回姓名"""
    if middle_name:
        full_name = f"{first_name} {middle_name} {last_name}"
    else:
        full_name = f"{first_name} {last_name}"
    return full_name.title()

musician = get_formatted_name("jimi", "hedrix")
print(musician)
musician = get_formatted_name("john", "lee", "hooker")
print(musician)

它运行的结果是:

Jimi Hedrix
John Hooker Lee

3、返回字典

函数可返回任何类型的值,包括列表和字典等较复杂的数据结构,举个例子:

def build_person(first_name, last_name, age=None):
    """返回一个字典,其中包含有关一个人的信息。"""
    person = {'姓': first_name, '名': last_name}
    if age:
        person['年龄'] = age
    return person

musician = build_person('北', '天',age=21)
print(musician)

它运行的结果是:

{'姓': '北', '名': '天', '年龄': 21}

六、传递列表

我们后面肯定会经常用到传入列表然后使用循环打印出列表的每一个值,例如我们定义一个用户列表然后使用函数对其中每个人打个招呼:

def greet_users(names):
    """向列表中的每个人打招呼。"""
    for name in names:
        msg = f"Hello {name}, How are you?"
        print(msg)

usernames = ['娜娜', '北天']
greet_users(usernames)

它运行的结果是:

Hello 娜娜, How are you?
Hello 北天, How are you?

七、变量作用域

变量作用域是指能够访问该变量的代码范围,分为三个层次,它们分别是局部作用域、外围作用域和全局作用域,其中:

  • 全局作用域:作用到整个模块中
  • 外围作用域:可以作用到内嵌函数
  • 局部作用域,仅作用于本函数内部

另外,不同作用域内的变量名可以相同,如果同名变量作用域出现重叠,除非特别声明,否则作用域小的变量将屏蔽作用域大的同名变量。

举个例子:

x = 3
def outfunc():
    x = 5
    def innerfunc():
        x = 7
        print('inner x:', x)
    innerfunc()
    print('outer x:', x)
outfunc()
print('global x:', x)

它运行的结果是:

inner x: 7
outer x: 5
global x: 3

需要注意的是,如果在内部函数中不修改非局部变量(包括全局变量和外围非全局变量)的值,而只是读取其值,则不用专门声明。

例如:

x = 3
def outfunc():
    y = 5
    def innerfunc():
        z = 7
        print('inner sum:', x + y + z)
    innerfunc()
    print('outer sum:', x + y)
outfunc()

它运行的结果是:

inner sum: 15
outer sum: 8

还有就是,如果在内部函数中需要修改非局部变量的值,则需要专门声明,其中修改全局变量需要使用关键字global声明,修改外围非全局变量需要使用关键字nonlocal声明。

例如:

x = 3
def outfunc():
    global x
    x += 2
    y = 5
    def innerfunc():
        global x
        nonlocal y
        x *= 2
        y *= 2
        z = 7
        print('inner x, y, z:', x, y, z)
        print('inner sum:', x + y +z)
    innerfunc()
    print('outer x, y:', x, y)
    print('outer sum:', x + y)
outfunc()
print('global x:', x)

它运行的结果是:

inner x, y, z: 10 10 7
inner sum: 27
outer x, y: 10 10
outer sum: 20
global x: 10

八、匿名函数

所谓匿名函数就是没有函数名的函数,常用于需要快速定义一个单行、功能简单的函数场合,Python通过关键字lambda来定义匿名函数,它是一个表达式,所以也叫lambda表达式。

它的一般语法格式是:

lambda [参数1 [, 参数2, ...参数n]]: 表达式

其参数列表允许为空,也不用写圆括号,表达式中不允许包含其他复杂的语句,但允许调用其他函数,也不用return返回值,表达式的结果就是表达值。

匿名函数可以赋值给变量(此时变量就引用了该匿名函数对象),并用该变量后加圆括号来调用该匿名函数,也可以不赋值给变量。

例如:

# 通过赋值给变量来调用lambda表达式
t = lambda: print("进行匿名函数演示")
t()
f = lambda x, y: x + y
print(f(2, 3))
# 下面例子没有把lambda表达式赋值给变量
def sum1(a, b, c):
    return lambda: a + b + c
print(sum1(1, 2, 3)())

它运行的结果是:

进行匿名函数演示
5
6

其中需要注意的是,最后一行sum1(1, 2, 3)的后面如果没有(),则输出的是返回的函数对象的内存地址。

九、最后我想说

函数部分的内容还远远没有总结完,还有超级多的知识需要大家去学习,上述文章只是总结了其中一部分知识,函数还有很多高阶函数的使用,后面如果用到了我再进行总结,目前就总结这么多吧,如果后续还有补充的我也会进行更新的。

网上有很多有关Python知识总结的博客和书籍,大家可以多去看看书,多去看看大佬总结的博客,我们一起学习。

欢迎大家进行留言讨论问题,也期待得到大家的支持,谢谢!

相关文章:

  • 19.请介绍一下重绘和回流
  • Flink / Scala - AllWindowFunction 与 KeyedProcessFunction 处理 TopK 问题
  • C++20之Concpet(概念部分,之二)
  • 【Spirng】@Component和@Configuration和@Bean的区别
  • 跟着江南一点雨学习springmvc(3)
  • 安卓手机使用Tasker实现应用级功能,屏幕翻译v9,翻译复制贴图
  • 一篇文章吃透 CSS3 属性: transition过渡 与 transform动画
  • 通讯录的动态版本
  • Docker搭建Kafka集群
  • WPS增加正则处理函数,简直如虎添翼
  • opencloudos容器镜像优化
  • 二.go语言条件与循环
  • 高阶函数1
  • 电子信息考研择校
  • 互联网数据管理平台
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 2017届校招提前批面试回顾
  • eclipse的离线汉化
  • JavaScript学习总结——原型
  • Kibana配置logstash,报表一体化
  • Koa2 之文件上传下载
  • Linux下的乱码问题
  • npx命令介绍
  • Python实现BT种子转化为磁力链接【实战】
  • scala基础语法(二)
  • SpringBoot 实战 (三) | 配置文件详解
  • vuex 笔记整理
  • WinRAR存在严重的安全漏洞影响5亿用户
  • -- 查询加强-- 使用如何where子句进行筛选,% _ like的使用
  • 少走弯路,给Java 1~5 年程序员的建议
  • 源码安装memcached和php memcache扩展
  • 职业生涯 一个六年开发经验的女程序员的心声。
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • C# - 为值类型重定义相等性
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • #stm32整理(一)flash读写
  • (06)Hive——正则表达式
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (pojstep1.1.2)2654(直叙式模拟)
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (附源码)计算机毕业设计SSM疫情社区管理系统
  • (六)软件测试分工
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (转)Scala的“=”符号简介
  • (转)一些感悟
  • ***监测系统的构建(chkrootkit )
  • .gitignore文件---让git自动忽略指定文件
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .Net Attribute详解(上)-Attribute本质以及一个简单示例
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET 的程序集加载上下文
  • .Net 应用中使用dot trace进行性能诊断
  • /etc/motd and /etc/issue