简明 Python 教程(第5章 函数)

本章介绍了函数的基本概念和使用方法,包括定义函数、传递参数、局部变量、全局变量、默认参数、关键字参数、返回值和文档字符串。

掌握这些概念对于编写结构化和可维护的Python代码至关重要。

定义函数

  • 使用def关键字

        定义函数始于def关键字,它告诉Python接下来是一个函数定义。

  • 函数名

  def关键字之后是函数名,它应该清晰地反映函数的功能。函数名遵循与变量相同的命名规则:必须以字母或下划线开头,不能使用Python的保留字,并且是大小写敏感的。

  • 圆括号和参数

        函数名后面跟着一对圆括号,其中包含零个或多个参数。参数是传递给函数的值,它们允许函数具有灵活性和通用性。

  • 参数列表

  1. 必需参数:在圆括号中按顺序列出,函数调用时必须提供。
  2. 关键字参数:使用=后跟默认值定义,如果函数调用时没有提供相应的实参,将使用默认值。
  3. 可变参数列表:使用*(用于非关键字参数)或**(用于关键字参数)定义,允许函数接受任意数量的额外参数。
  • 函数体

函数的定义以冒号(:)结束,后跟一个缩进的代码块,这是函数体。函数体中的代码定义了函数执行的操作。

  • 返回值

使用return语句从函数返回值。当return语句执行时,函数将立即结束,并返回指定的值给调用者。如果函数没有返回值,return可以不带任何表达式,或者根本不写return语句(在这种情况下,函数默认返回None)。

  • 示例

下面是一个简单的函数定义示例,该函数接受两个参数,计算它们的和,并返回结果:

def add_numbers(a, b): """ 计算并返回两个数字的和。 参数:  a (int/float): 第一个数字。 b (int/float): 第二个数字。 返回: int/float: 两个数字的和。 """ result = a + b return result 
# 调用函数 
sum = add_numbers(3, 5) 
print("两个数的和是:", sum) # 输出: 两个数的和是: 8

在这个例子中,add_numbers是一个函数名,它接受两个参数ab。函数体只有一行代码,计算ab的和,并将结果存储在变量result中。然后,使用return语句将结果返回给调用者。

函数定义是Python编程中的基础概念之一,它使得代码更加模块化、可重用和易于维护。通过定义函数,你可以创建复杂的程序结构,并将任务分解为更小、更易于管理的部分。

使用函数形参

  • 形参(formal parameters)是在函数定义中指定的变量,用于接收函数调用时传入的值(实参)。
  • 函数调用时,实参的顺序必须与形参的顺序相匹配。

局部变量

  • 在函数内部声明的变量是局部变量,它们的作用域仅限于函数内部。
  • 改变局部变量的值不会影响全局变量(除非使用global关键字)。

使用global语句

  • 何时使用global语句

  1. 当你想要在函数内部修改一个全局变量的值时。

  2. 当你想要在函数内部创建一个新的全局变量时(不推荐,因为这可能会导致命名冲突和代码难以理解)。
  3. 当你想要确保函数内部使用的变量是全局作用域中的变量,而不是在函数内部新定义的局部变量时。
  •  如何使用global语句

   global语句通常位于函数体内部,它告诉Python解释器后续声明的变量是全局变量。以下是           使用global语句的基本语法:

def my_function(): global global_variable global_variable = "我是全局变量" # 其他代码... 
# 函数外部定义全局变量 
global_variable = "原始全局变量值" 
# 调用函数 my_function() 
# 打印全局变量的值,以验证它已被函数修改 
print(global_variable) # 输出: 我是全局变量

在这个例子中,global语句在函数my_function内部声明了global_variable为全局变量。这意味着当函数内部对global_variable进行赋值操作时,它实际上是在修改全局作用域中的变量,而不是在函数内部创建一个新的局部变量。

  •  注意事项

  1. 过度使用global语句可能会导致代码难以理解和维护,因为它破坏了函数的封装性和局部性。
  2. 在函数内部尽量避免修改全局变量,这可能会导致代码中的bug更难发现和修复。
  3. 在同一个函数中,如果你需要声明多个全局变量,可以在global语句后面列出所有这些变量的名字,用空格分隔,例如:global var1, var2, var3
  4. 在Python 3中,如果你想要修改一个全局变量,除了使用global语句外,还可以使用nonlocal语句来声明一个变量为嵌套作用域中的变量(当函数内部有多层嵌套作用域时使用)。

默认参数值

在Python中,函数默认参数值是一个非常方便的特性,它允许在定义函数时为参数指定默认值。这意味着在调用函数时,如果没有为这些参数提供值,Python将自动使用它们的默认值。通过使用默认参数值,你可以编写出更加灵活和用户友好的函数,使它们更容易被调用和重用。

  • 定义带有默认参数值的函数

当你定义一个函数时,可以在参数列表中为参数赋予默认值。这通过在参数名后面直接指定一个等号和默认值来实现。例如:

def greet(name, greeting='Hello'): print(greeting, name)

在这个例子中,greet函数有两个参数:namegreetinggreeting参数的默认值是'Hello'。当你调用greet函数时,如果没有提供greeting参数,它将自动使用'Hello'作为默认值。

  • 调用带有默认参数值的函数

调用带有默认参数值的函数时,可以省略具有默认值的参数:

greet('Alice') # 输出: Hello Alice greet('Bob', 'Good morning') # 输出: Good morning Bob

在第一个调用中,我们只提供了name参数的值,greeting参数使用了默认值'Hello'。在第二个调用中,我们提供了namegreeting两个参数的值,所以greeting参数的值被覆盖为'Good morning'

  • 注意事项

  1. 默认参数值在函数定义时被计算一次,并在函数的整个生命周期内保持不变。这意味着如果你将可变对象(如列表或字典)作为默认值,那么所有调用该函数的实例都将共享同一个对象。例如:

    def func(a, b=None):b = b or areturn a + bprint(func(1))  # 输出: 2,因为b是None,所以返回1+1
    print(func(1, 2))  # 输出: 3
    

    在这个例子中,b被初始化为None,然后使用or运算符赋值为a的值。这意味着每次调用func(1)时,都会返回2,因为b被设置为1

  2. 从Python 3开始,不建议使用可变对象作为默认参数值,因为这可能导致意外的行为。如果你需要一个默认的可变对象,最好在函数内部创建一个新的对象实例。

  3. 默认参数值应该用于那些你希望在大多数情况下保持不变的值,而不是用于那些可能会频繁变化的值。

关键字参数(命名参数)

在Python中,关键字参数(也称为命名参数)允许你在调用函数时明确指定参数的名称和值。这种语法提供了一种清晰的方式来传递参数,尤其是当函数有很多参数时,它可以使得代码更易读和更易于维护。关键字参数是Python中一个非常有用的功能,它提高了函数的可读性和灵活性。通过使用关键字参数,你可以编写出更加清晰和易于维护的代码。

  • 基本语法

当你定义一个函数时,你可以使用关键字参数来指定参数的名称和默认值。在调用函数时,你可以通过在参数值前加上参数名和等号来明确地传递每个参数:

def func(a, b, c=0): return a + b + c 
# 使用关键字参数调用函数 
result = func(a=1, b=2, c=3)

在这个例子中,func函数有三个参数:abcc是一个具有默认值0的关键字参数。在调用func时,我们使用了关键字参数来指定每个参数的值。

  • 优点

  1. 清晰性:关键字参数使得函数调用更易于理解,因为参数的用途在调用时就被明确了。
  2. 灵活性:你可以只传递具有默认值的参数,或者按需传递任意数量的参数。
  3. 顺序无关性:使用关键字参数调用函数时,不需要按照函数定义中的参数顺序。
  • 与位置参数结合使用

关键字参数可以与位置参数结合使用,但必须在位置参数之后:

def func(first, second, third='third'): return first + second + third 
# 混合使用位置参数和关键字参数 
result = func(1, second=2, third='other third')

在这个例子中,我们首先通过位置传递了first参数的值1,然后使用关键字参数传递了secondthird的值。

  • 注意事项

  1. 确保在使用关键字参数时,所有必需的位置参数都已经提供了值,否则你会遇到TypeError
  2. 如果函数定义中使用了*args**kwargs,那么所有的关键字参数都应该放在*args**kwargs之后。
  3. 在文档字符串(DocString)中明确指出哪些参数是必需的,哪些有默认值,以及它们的含义,这有助于其他开发者理解和使用你的函数。

可变参数列表

在Python中,可变参数列表允许函数接受任意数量的位置参数或关键字参数,提供了极大的灵活性。这在你需要创建一个可以接受多种参数组合的函数时特别有用。以下是两种主要的可变参数列表:

  • 非关键字可变参数(*args)

使用*符号定义非关键字可变参数,通常称为args。这允许函数接受任意数量的位置参数,并将它们作为一个元组处理。

def my_function(*args): for arg in args: print(arg)

调用这个函数时,可以传递任意数量的参数:

my_function(1, 2, 3, 'a', 'b')

在这个例子中,args是一个元组,包含了所有传递给my_function的参数。

  • 关键字可变参数(**kwargs)

使用**符号定义关键字可变参数,通常称为kwargs。这允许函数接受任意数量的关键字参数,并将它们作为一个字典处理。

def my_function(**kwargs): for key, value in kwargs.items(): print(f"{key}: {value}")

调用这个函数时,可以传递任意数量的关键字参数:

my_function(name='Alice', age=25, city='Wonderland')

在这个例子中,kwargs是一个字典,包含了所有传递给my_function的关键字参数。

  • 同时使用两种可变参数

你可以在同一个函数定义中同时使用*args**kwargs,但*args必须在**kwargs之前:

def my_function(*args, **kwargs): print("Positional arguments:", args) print("Keyword arguments:", kwargs) 
my_function(1, 2, 'a', name='Alice', age=25)

在这个例子中,args将接收所有位置参数,而kwargs将接收所有关键字参数。

  • 注意事项

  1. 当使用可变参数列表时,函数内部的参数列表中出现的普通参数(非可变参数列表)必须在可变参数列表之前定义。
  2. 如果你使用*args,那么所有跟随其后的位置参数都将被视为可变参数列表的一部分。
  3. 类似地,如果你使用**kwargs,那么所有跟随其后的关键字参数都将被视为关键字可变参数列表的一部分。
  4. 可变参数列表使得函数调用更加灵活,但也可能导致函数的签名不够明确,因此在设计函数时应当谨慎使用。

通过使用可变参数列表,你可以创建更加通用和灵活的函数,以适应各种不同的调用场景。

return语句

  • return语句用于从函数中返回一个值给调用者。
  • 如果函数没有返回值,return可以不带任何值。
  • 没有return语句的函数默认返回None

使用DocStrings

DocStrings(文档字符串)是Python中用于记录函数、类、模块等元素的文档信息的一种约定。它们通常位于被记录元素的直接下方,并被三引号(单引号'''或双引号""")包围。DocStrings提供了一种标准的方式来嵌入文档到Python代码中,这些文档可以通过内置的__doc__属性来访问。

  • 基本语法

DocStrings的基本语法是在三引号内编写文本,可以包含多行文本:

def my_function(): """ 这是一个文档字符串的例子。 这里可以包含多行文本,用于描述函数的功能、参数、返回值等。 """ pass
  • 内容约定

  1. 首行:通常是最重要的一行,应该简洁地描述函数或类的作用。
  2. 后续行:提供更详细的描述,包括参数的说明、函数的副作用、返回值的描述等。
  3. 格式:推荐使用reStructuredText(reST)格式,这是一种用于文档的轻量级标记语言。
  • 访问DocStrings

你可以通过__doc__属性来访问任何对象的DocString:

print(my_function.__doc__)
  • 使用DocStrings的最佳实践

  1. 始终使用:即使是简单的函数或类,也应该有一个DocString来描述它们的基本功能。
  2. 保持更新:随着代码的变化,确保DocStrings也同步更新,以保持信息的准确性。
  3. 清晰的描述:DocStrings应该清晰、准确地描述元素的功能和用法。
  4. 参数和返回值:如果函数有参数或返回值,应该在DocString中详细说明。
  5. 例子:如果适用,提供一个使用函数的简短示例可以增加文档的可读性。
  • 示例

下面是一个包含DocString的函数示例,以及如何访问和打印它的DocString:

def greet(name, greeting='Hello'): """ 打印问候语。 参数: name (str): 要问候的人的名字。 greeting (str): 问候语的开始部分,默认为 'Hello'。 返回: str: 完整的问候语字符串。 """ return f"{greeting}, {name}!" # 访问并打印函数的DocString 
print(greet.__doc__) 
# 调用函数并打印结果 
print(greet('Alice')) # 输出: Hello, Alice!

在这个例子中,greet函数的DocString详细描述了函数的作用、参数和返回值。通过打印greet.__doc__,我们可以看到完整的文档字符串。

DocStrings是Python文档化的一个重要部分,它们使得代码更加自解释,有助于其他开发者理解和使用你的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/772705.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php 快速入门(五)

一、文件上传 文件上传的基础知识&#xff1a; 首先&#xff0c;在客户端form表达设置&#xff0c;选择上传的文件然后&#xff0c;在服务器对上传文件进行操作处理 1.1 关于前台页面 必须设置 form 表单项&#xff1a; <html><head><title>文件上传<…

Python+Pytest+Allure搭建接口自动化测试框架

最近在用PythonPytestAllure搭建接口自动化测试框架 具体的框架要求&#xff1a; 1&#xff0c;使用Pytest进行测试用例编写和执行 2&#xff0c;使用Allure生成漂亮的测试报告 3&#xff0c;并且要求有断言方法 初步的框架设计如下&#xff0c;后期可以进一步添加很多功能…

Consul集群搭建看这篇就够了(consul cluster configuration )

Consul 是一种用于服务发现、配置和分布式一致性的开源工具和平台。它由 HashiCorp 公司开发和维护&#xff0c;旨在简化构建和维护分布式系统的任务。 Consul 提供了许多功能&#xff0c;包括&#xff1a; 服务发现&#xff1a;Consul允许服务注册和发现。当服务启动时&#…

《35岁,程序员的危机or转机?——深度剖析程序员职业发展之路》

一、引言 35岁,对于很多程序员来说是一个让人焦虑的年龄。在互联网行业,35岁往往被视为职业生涯的分水岭。许多程序员开始担心,随着年龄的增长,他们的职业发展是否会受到限制。这种担忧并非毫无根据。互联网行业瞬息万变,新技术层出不穷,对程序员的学习能力和适应能力提出了很高…

达梦查询text转换问题

bug&#xff1a;表字段为TEXT&#xff0c;数据返回页面时&#xff0c;打断点查看其为NClobProxyImpl对象 org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/quality].[dispatcherServlet] -Servlet.service() for servlet [dispatcherServlet] in context with …

【 C++ 】如何查看项目中使用的c++版本

如何查看项目中使用的c版本 std::cout << __cplusplus << std::endl;在项目任一位置&#xff0c;创建.cpp文件&#xff08; C/C Source.File&#xff09; main.cpp #include <iostream>int main() {std::cout << "Hello World!\n";std::co…

C++流插入、提取重载详解

内置类型支持流插入 自定义类型不支持流插入 注意&#xff1a;运算符重载如果有两个操作数的时候&#xff0c;第一个为左操作数&#xff0c;第二个为右操作数 而成员函数的第一个参数默认为this基类&#xff0c;而this参数又不能显式书写&#xff0c;所以没法改 也就是说第一个…

JAVA-----

标识符 标识符可以简单的理解为一个名字&#xff0c;在Java中&#xff0c;我们需要给代码中的很多元素起名字&#xff0c;包括类名、方法名、字段名、变量名等等。我们给对应元素起的名称就被叫做是标识符。一个正确的标识符需要遵循以下规则&#xff1a; 1.标识符可以由字母、…

PYTHON初级笔记1

0、python&#xff1f; 简单的编程语言 python环境搭建&#xff1a; ①、开发环境&#xff1a;vscode、sublime、pycharm...... ②、运行环境&#xff1a;cpython解释器 python如何写代码&#xff1f; ①、在终端上的命令行上写&#xff0c;可以是我们cmd的中终端&#xff0c;…

MATLAB 公共区域的点云合并(46)

MATLAB 公共区域的点云合并(46) 一、算法介绍二、算法实现1.代码2.效果一、算法介绍 点云配准后,或者公共区域存在多片点云对场景进行冗余过量表达时,我们需要将点云进行合并,Matlab点云工具中提供了这样的合并函数,通过指定网格步长,对初始点云进行过滤。 函数主要实…

分治——快速排序算法

例题一 解法&#xff08;快排思想 - 三指针法使数组分三块&#xff09;&#xff1a; 算法思路&#xff1a; 类⽐数组分两块的算法思想&#xff0c;这⾥是将数组分成三块&#xff0c;那么我们可以再添加⼀个指针&#xff0c;实现数组分 三块。 设数组⼤⼩为 n &#xff0c…

非计算机科班如何丝滑转码:规划、前景与行动建议

近年来&#xff0c;计算机领域因其广阔的应用前景和优厚的薪资待遇&#xff0c;吸引了众多非计算机科班出身的人士想要转行。然而&#xff0c;对于没有专业背景的他们来说&#xff0c;如何实现从其他行业到计算机领域的丝滑转码&#xff0c;确实是一个值得深思的问题。以下是我…

nextjs getServerSideProps 获取url中的参数

在 Next.js 中&#xff0c;可以使用 getServerSideProps 函数的上下文对象来获取 URL 中的参数。getServerSideProps 函数接收一个上下文对象&#xff08;通常命名为 context&#xff09;&#xff0c;其中包含了有关请求的信息&#xff0c;包括查询参数、路径参数等。 以下是一…

数据分析web可视化神器---streamlit框架,无需懂前端也能搭建出精美的web网站页面

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属的专栏&#xff1a;数据分析系统化教学&#xff0c;零基础到进阶实战 景天的主页&#xff1a;景天科技苑 文章目录 Streamlit什么是streamli…

Godot 学习笔记(5):国际化多语言翻译,包含常用10种语言机翻!

文章目录 前言国际化翻译Api选择小牛测试 语言选择代码逻辑实体对象翻译帮助类导出模板读取文件翻译测试多语言测试 综合翻译文件准备测试代码测试结果 完整代码实体类翻译帮助类网络帮助类 最终效果翻译前翻译中翻译后 总结 前言 为了面向更大的市场&#xff0c;国际化是肯定…

毫米波雷达简介

毫米波雷达简介 附赠自动驾驶学习资料和量产经验&#xff1a;链接 1. 概述 1.1 发展历史 RADAR是RAdio Detection And Ranging的缩写。 1936年1月&#xff0c;英国架起了第一个雷达站&#xff0c;用于监测德国战机。从此之后&#xff0c;雷达技术开始蓬勃发展。 雷达的频段很…

软件测试基础(1)

软件测试的生命周期 软件测试的生命周期: 需求分析 -> 测试计划 -> 测试设计, 测试开发 -> 测试执行 -> 测试评估. 软件测试 & 软件开发的生命周期 1.需求阶段 测试人员了解需求, 对需求进行分解, 得出测试需求. 2.计划阶段 根据需求编写测试计划/测试方案 3…

Web核心

目录 Web核心HTTP概念&#xff1a;协议特点&#xff1a;请求数据格式响应数据格式 Tomcat简介基本使用配置部署项目IDEA中创建 Maven Web 项目 IDEA使用Tomcat Servlet简介快速入门执行流程生命周期体系结构Servlet urlPattern配置一个Servlet&#xff0c;可以配置多个 urlPatt…

Java函数式编程-Stream流

Java函数式编程-Stream流 1.概述为什么学&#xff1f;函数式编程思想优点 2.Lambda表达式2.1概述2.2核心原则2.3 基本格式例一例二 2.4省略规则 3.Stream流概述3.2案例数据准备3.3快速入门3.3.1需求3.3.2实现 3.4常用操作3.4.1创建流3.4.2中间操作filtermapdistinctsortedlimit…

java-springboot实现图片的上传

我们在resources目录下创建image目录来存放上传的图片 service层懒的写&#xff0c;就都写controller层了。 RestController RequestMapping("/upload") public class upload {PostMapping("/pic")public String upLoad(RequestParam("multipartFile…