主页
  • 主页
  • 分类
  • 热文
  • 教程
  • 面试
  • 标签
Python

Python 基础

Python 主页
Python 概述
Python 历史
Python 功能
Python 与 C++
Python Hello World
Python 应用领域
Python 解释器及其模式
Python 环境设置
Python 虚拟环境
Python 语法
Python 变量
Python 数据类型
Python 类型转换
Python Unicode 系统
Python 文字
Python 运算符
Python 算术运算符
Python 比较运算符
Python 赋值运算符
Python 逻辑运算符
Python 位运算符
Python 成员运算符
Python 身份运算符
Python 运算符优先级
Python 注释
Python 用户输入
Python 数字
Python 布尔值

Python 控制语句

Python 控制流
Python 决策
Python if 语句
Python if-else 语句
Python 嵌套 if 语句
Python match-case 语句
Python 循环
Python For 循环
Python for-else 循环
Python while 循环
Python break 语句
Python Continue 语句
Python pass 语句
Python 嵌套循环

Python 函数和模块

Python 函数
Python 默认参数
Python 关键字参数
Python 关键字专用参数
Python 位置参数
Python 仅限位置参数
Python 任意或可变长度参数
Python 变量作用域
Python 函数注释
Python 模块
Python 内置函数

Python 字符串

Python 字符串
Python 字符串切片
Python 字符串修改
Python 字符串连接
Python 字符串格式化
Python 转义字符
Python 字符串方法
Python 字符串练习

Python 列表

Python 列表
Python 访问列表项
Python 更改列表项
Python 添加列表项
Python 删除列表项
Python 循环列表
Python 列表推导式
Python 排序列表
Python 复制列表
Python 合并列表
Python 列表方法
Python 列表练习

Python 元组

Python 元组
Python 访问元组项
Python 更新元组
Python 解包元组项
Python 循环元组
Python 合并元组
Python 元组方法
Python 元组练习

Python 集合

Python 集合
Python 访问集合项
Python 添加集合项
Python 删除集合项
Python 循环集合
Python 合并集合
Python 复制集合
Python 集合运算符
Python 集合方法
Python 集合练习

Python 字典

Python 字典
Python 访问字典项
Python 更改字典项
Python 添加字典项
Python 移除字典项
Python 字典视图对象
Python 循环字典
Python 复制字典
Python 嵌套字典
Python 字典方法
Python 字典练习

Python 数组

Python 数组
Python 访问数组项
Python 添加数组项
Python 移除数组项
Python 循环数组
Python 复制数组
Python 反转数组
Python 排序数组
Python 合并数组
Python 数组方法
Python 数组练习

Python 文件处理

Python 文件处理
Python 文件写入
Python 文件读取
Python 重命名和删除文件
Python 目录
Python 文件方法
Python 文件/目录方法
Python OS.Path 方法

Python 面向对象编程

Python OOP 概念
Python 类和对象
Python 类属性
Python 类方法
Python 静态方法
Python 构造函数
Python 访问修饰符
Python 继承
Python 多态
Python 方法重写
Python 方法重载
Python 动态绑定
Python 动态类型
Python 抽象
Python 封装
Python 接口
Python 包
Python 内部类
Python 匿名类和对象
Python 单例类
Python 包装器类
Python 枚举
Python 反射

Python 错误和异常

Python 语法错误
Python 异常处理
Python Try-Except
Python Try-Finally
Python 抛出异常
Python 异常链
Python 嵌套 try
Python 用户定义异常
Python 日志记录
Python 断言
Python 内置异常

Python 多线程

Python 多线程
Python 线程生命周期
Python 创建线程
Python 启动线程
Python 合并线程
Python 命名线程
Python 线程调度
Python 线程池
Python 主线程
Python 线程优先级
Python 守护线程
Python 线程同步

Python 同步

Python 线程间通信
Python 死锁
Python 中断线程

Python 网络

Python 网络编程
Python 套接字编程
Python URL 处理
Python 泛型

Python 杂项

Python Date and Time
Python math模块
Python 迭代器
Python 生成器
Python 闭包
Python 装饰器
Python 递归
Python 正则表达式
Python Pip
Python 数据库访问
Python 弱引用
Python 序列化
Python 模板技术
Python 输出格式化
Python 性能测量
Python 数据压缩
Python 通用网关接口
Python XML 处理
Python 用户界面(GUI)
Python 命令行参数
Python Docstrings
Python JSON
Python 发送电子邮件
Python 进一步扩展
Python 工具/实用程序
Python GUI

Python 高级概念

Python 抽象基类
Python 自定义异常
Python 高阶函数
Python 对象的内部机制
Python 内存管理
Python 元类
Python 元编程
Python 模拟与桩
Python 猴子补丁
Python 信号处理
Python 类型提示
Python 进行自动化
Python Humanize包
Python 上下文管理器
Python 协程
Python 描述符
Python 内存泄漏
Python 不可变数据结构

基础

Python 主页
Python 概述
Python 历史
Python 功能
Python 与 C++
Python Hello World
Python 应用领域
Python 解释器及其模式
Python 环境设置
Python 虚拟环境
Python 语法
Python 变量
Python 数据类型
Python 类型转换
Python Unicode 系统
Python 文字
Python 运算符
Python 算术运算符
Python 比较运算符
Python 赋值运算符
Python 逻辑运算符
Python 位运算符
Python 成员运算符
Python 身份运算符
Python 运算符优先级
Python 注释
Python 用户输入
Python 数字
Python 布尔值

控制语句

Python 控制流
Python 决策
Python if 语句
Python if-else 语句
Python 嵌套 if 语句
Python match-case 语句
Python 循环
Python For 循环
Python for-else 循环
Python while 循环
Python break 语句
Python Continue 语句
Python pass 语句
Python 嵌套循环

函数和模块

Python 函数
Python 默认参数
Python 关键字参数
Python 关键字专用参数
Python 位置参数
Python 仅限位置参数
Python 任意或可变长度参数
Python 变量作用域
Python 函数注释
Python 模块
Python 内置函数

字符串

Python 字符串
Python 字符串切片
Python 字符串修改
Python 字符串连接
Python 字符串格式化
Python 转义字符
Python 字符串方法
Python 字符串练习

列表

Python 列表
Python 访问列表项
Python 更改列表项
Python 添加列表项
Python 删除列表项
Python 循环列表
Python 列表推导式
Python 排序列表
Python 复制列表
Python 合并列表
Python 列表方法
Python 列表练习

元组

Python 元组
Python 访问元组项
Python 更新元组
Python 解包元组项
Python 循环元组
Python 合并元组
Python 元组方法
Python 元组练习

集合

Python 集合
Python 访问集合项
Python 添加集合项
Python 删除集合项
Python 循环集合
Python 合并集合
Python 复制集合
Python 集合运算符
Python 集合方法
Python 集合练习

字典

Python 字典
Python 访问字典项
Python 更改字典项
Python 添加字典项
Python 移除字典项
Python 字典视图对象
Python 循环字典
Python 复制字典
Python 嵌套字典
Python 字典方法
Python 字典练习

数组

Python 数组
Python 访问数组项
Python 添加数组项
Python 移除数组项
Python 循环数组
Python 复制数组
Python 反转数组
Python 排序数组
Python 合并数组
Python 数组方法
Python 数组练习

文件处理

Python 文件处理
Python 文件写入
Python 文件读取
Python 重命名和删除文件
Python 目录
Python 文件方法
Python 文件/目录方法
Python OS.Path 方法

面向对象编程

Python OOP 概念
Python 类和对象
Python 类属性
Python 类方法
Python 静态方法
Python 构造函数
Python 访问修饰符
Python 继承
Python 多态
Python 方法重写
Python 方法重载
Python 动态绑定
Python 动态类型
Python 抽象
Python 封装
Python 接口
Python 包
Python 内部类
Python 匿名类和对象
Python 单例类
Python 包装器类
Python 枚举
Python 反射

错误和异常

Python 语法错误
Python 异常处理
Python Try-Except
Python Try-Finally
Python 抛出异常
Python 异常链
Python 嵌套 try
Python 用户定义异常
Python 日志记录
Python 断言
Python 内置异常

多线程

Python 多线程
Python 线程生命周期
Python 创建线程
Python 启动线程
Python 合并线程
Python 命名线程
Python 线程调度
Python 线程池
Python 主线程
Python 线程优先级
Python 守护线程
Python 线程同步

同步

Python 线程间通信
Python 死锁
Python 中断线程

网络

Python 网络编程
Python 套接字编程
Python URL 处理
Python 泛型

杂项

Python Date and Time
Python math模块
Python 迭代器
Python 生成器
Python 闭包
Python 装饰器
Python 递归
Python 正则表达式
Python Pip
Python 数据库访问
Python 弱引用
Python 序列化
Python 模板技术
Python 输出格式化
Python 性能测量
Python 数据压缩
Python 通用网关接口
Python XML 处理
Python 用户界面(GUI)
Python 命令行参数
Python Docstrings
Python JSON
Python 发送电子邮件
Python 进一步扩展
Python 工具/实用程序
Python GUI

高级概念

Python 抽象基类
Python 自定义异常
Python 高阶函数
Python 对象的内部机制
Python 内存管理
Python 元类
Python 元编程
Python 模拟与桩
Python 猴子补丁
Python 信号处理
Python 类型提示
Python 进行自动化
Python Humanize包
Python 上下文管理器
Python 协程
Python 描述符
Python 内存泄漏
Python 不可变数据结构

Python 函数


上一章 下一章

Python函数是一段组织良好且可重用的代码,用于执行单一且相关的动作。函数为您的应用程序提供了更好的模块化,并且具有高度的代码复用性。

自上而下的方法来构建处理逻辑涉及到定义独立的可重用函数块。一个Python函数可以从任何其他函数中通过传递所需数据(称为参数或实参)来调用来。被调用的函数会将其结果返回给调用环境。

Python 函数

Python函数类型

Python提供了以下几种类型的函数:

序号 类型 描述
1 内置函数 Python的标准库包含了大量的内置函数。一些Python的内置函数包括print()、int()、len()、sum()等。这些函数总是可用的,因为一旦启动Python解释器,它们就会被加载到计算机的内存中。
2 在内置模块中定义的函数 标准库还捆绑了一些模块。每个模块定义了一组函数。这些函数不是直接可用的。你需要从各自的模块导入它们到内存中。
3 用户定义的函数 除了内置函数和内置模块中的函数外,您还可以创建自己的函数。这些函数被称为用户定义的函数。

定义Python函数

您可以定义自定义函数以提供所需的特性。以下是定义Python函数的一些简单规则:

  • 函数块以关键字def开始,后面跟着函数名和括号()。
  • 任何输入参数或实参都应该放置在这些括号内。您也可以在这些括号内定义参数。
  • 函数的第一行可以是一个可选的语句;即函数的文档字符串或docstring。
  • 每个函数内的代码块以冒号(:)开始,并且是缩进的。
  • return [expression]语句退出一个函数,可选地向调用者返回一个表达式。没有参数的return语句等同于return None。

定义Python函数的语法

def function_name(parameters):
   "function_docstring"
   function_suite
   return [expression]

默认情况下,参数具有位置行为,您需要按照它们被定义的顺序提供它们。

一旦函数被定义了,您可以通过从另一个函数中调用它或者直接从Python提示符调用来执行它。

定义Python函数的例子

下面的例子展示了如何定义一个名为greetings的函数。括号是空的,因此没有参数。这里,第一行是一个docstring,函数块以return语句结束。

def greetings():
   "这是greetings函数的docstring"
   print("Hello World")
   return

当这个函数被调用时,会打印出“Hello World”消息。

调用Python函数

定义一个函数只是给它一个名字,指定了函数要包含的参数,并结构化了代码块。一旦函数的基本结构确定了,您就可以通过使用函数名本身来调用它。如果函数需要任何参数,它们应该在括号内传递。如果函数不需要任何参数,则括号应保持为空。

Python函数调用示例

下面是如何调用printme()函数的例子:

# 函数定义在这里
def printme(str):
   "这将在函数中打印一个传递的字符串"
   print(str)
   return;

# 现在你可以调用这个函数
printme("我是第一次调用用户定义的函数!")
printme("再次第二次调用相同的函数")

当上述代码被执行时,会产生如下的输出:

我是第一次调用用户定义的函数!
再次第二次调用相同的函数

引用传递与值传递

在像C和C++这样的编程语言中,有两种主要的方式将变量传递给函数,即值传递和引用传递(也称为按引用传递和按值传递)。然而,在Python中我们传递变量到函数的方式与其他语言不同。

值传递

当在一个函数调用中传递一个变量时,实际参数的值被复制到形式参数代表的变量中。因此,对形式参数所做的任何更改都不会反映在实际参数中。这种传递变量的方式被称为值传递。

引用传递

在这种方式下,传递的是内存中对象的一个引用。形式参数和实际参数(调用代码中的变量)都指向内存中的同一个对象。因此,对形式参数所做的更改确实会在实际参数中反映出来。

Python使用的是引用传递机制。由于Python中的变量是对内存中对象的标签或引用,因此作为实际参数以及形式参数使用的变量实际上都指向内存中的同一个对象。我们可以通过检查传递变量的id()来验证这一事实。

按引用传递 vs 按值传递

示例

在下面的例子中,我们正在检查变量的id()。

def testfunction(arg):
   print("在函数内部的ID:", id(arg))

var = "Hello"
print("传递前的ID:", id(var))
testfunction(var)

如果上述代码被执行,那么传递前和在函数内部的id()将会显示出来。

传递前的ID: 1996838294128
在函数内部的ID: 1996838294128

行为还取决于传递的对象是否可变。Python中的数字对象是不可变的。当一个数字对象被传递,并且函数改变了形式参数的值时,它实际上是在内存中创建了一个新的对象,而不改变原来的变量。

示例

下面的例子展示了当一个不可变对象被传递给一个函数时的行为。

def testfunction(arg):
   print("在函数内部的ID:", id(arg))
   arg = arg + 1
   print("增量后的新对象", arg, id(arg))

var = 10
print("传递前的ID:", id(var))
testfunction(var)
print("函数调用后的值", var)

它将产生如下的输出:

传递前的ID: 140719550297160
在函数内部的ID: 140719550297160
增量后的新对象 11 140719550297192
函数调用后的值 10

现在让我们传递一个可变对象(例如列表或字典)到一个函数。它同样是以引用的方式传递的,因为在传递前后列表的id()相同。但是,如果我们修改函数内部的列表,它的全局表示也会反映出这种变化。

示例

这里我们传递一个列表,在列表中追加一个新的项目,并查看原始列表对象的内容,我们会发现它已经发生了变化。

def testfunction(arg):
   print("在函数内部:", arg)
   print("在函数内部的ID:", id(arg))
   arg.append(100)

var = [10, 20, 30, 40]
print("传递前的ID:", id(var))
testfunction(var)
print("函数调用后的列表", var)

它将产生如下的输出:

传递前的ID: 2716006372544
在函数内部: [10, 20, 30, 40]
在函数内部的ID: 2716006372544
函数调用后的列表 [10, 20, 30, 40, 100]

Python函数参数

函数参数是在函数被调用时传入的值或变量。函数的行为通常依赖于传入的参数。

在定义函数时,你在括号内指定了一组变量(称为形式参数)。这些参数作为数据占位符,这些数据将在函数被调用时传递给函数。当函数被调用时,必须为每个形式参数提供实际的值。这些被称为实际参数。

函数参数

示例

让我们修改greetings函数,并添加一个参数name。作为实际参数传递给函数的字符串成为函数内部的name变量。

def greetings(name):
   "这是greetings函数的docstring"
   print("Hello {}".format(name))
   return
   
greetings("Samay")
greetings("Pratima")
greetings("Steven")

此代码将产生如下的输出:

Hello Samay
Hello Pratima
Hello Steven

Python函数参数的类型

根据在定义Python函数时参数是如何声明的,它们被分类为以下几类:

  • 位置参数或必需参数
  • 关键字参数
  • 默认参数
  • 仅位置参数
  • 仅关键字参数
  • 可变长参数或任意参数

位置参数或必需参数

必需参数是在正确的顺序下传递给函数的参数。在这里,函数调用中的参数数量必须与函数定义完全匹配,否则代码会给出语法错误。

示例

在下面的代码中,我们在没有任何参数的情况下调用函数printme(),这将导致错误。

# 函数定义在这里
def printme(str):
   "这将在函数中打印一个传递的字符串"
   print(str)
   return;

# 现在你可以调用printme函数
printme()

当上述代码被执行时,会产生如下的结果:

Traceback (most recent call last):
   File "test.py", line 11, in <module>
      printme();
TypeError: printme() takes exactly 1 argument (0 given)

关键字参数

关键字参数与函数调用相关。当你在函数调用中使用关键字参数时,调用者通过参数名识别参数。这允许你跳过某些参数或将它们放在不同的顺序中,因为Python解释器能够使用提供的关键字将值与参数相匹配。

示例1

下面的例子展示了如何在Python中使用关键字参数。

# 函数定义在这里
def printme(str):
   "这将在函数中打印一个传递的字符串"
   print(str)
   return;

# 现在你可以调用printme函数
printme(str = "我的字符串")

当上述代码被执行时,会产生如下的结果:

我的字符串

示例2

下面的例子给出了更清晰的画面。注意参数的顺序并不重要。

# 函数定义在这里
def printinfo(name, age):
   "这将在函数中打印传递的信息"
   print("姓名: ", name)
   print("年龄 ", age)
   return;

# 现在你可以调用printinfo函数
printinfo(age=50, name="miki")

当上述代码被执行时,会产生如下的结果:

姓名: miki
年龄 50

默认参数

默认参数是指在函数调用时如果没有为某个参数提供值,则该参数将采用默认值。

示例

下面的例子展示了默认参数的概念,它在没有传递年龄时打印默认年龄。

# 函数定义在这里
def printinfo(name, age=35):
   "这将在函数中打印传递的信息"
   print("姓名: ", name)
   print("年龄 ", age)
   return;

# 现在你可以调用printinfo函数
printinfo(age=50, name="miki")
printinfo(name="miki")

当上述代码被执行时,会产生如下的结果:

姓名: miki
年龄 50
姓名: miki
年龄 35

仅位置参数

那些只能通过其在函数调用中的位置来指定的参数被称为仅位置参数。它们通过在所有仅位置参数之后放置一个“/”在函数的参数列表中来定义。此功能是在Python 3.8版本发布时引入的。

使用这种类型的参数的好处是它确保了函数按照正确的顺序使用正确的参数被调用。仅位置参数应该作为位置参数而不是关键字参数传递给函数。

示例

在下面的例子中,我们定义了两个仅位置参数,分别是"x"和"y"。这个方法应该按照参数声明的顺序以位置参数的形式被调用,否则我们将得到一个错误。

def posFun(x, y, /, z):
    print(x + y + z)

print("评估仅位置参数: ")
posFun(33, 22, z=11) 

它将产生如下的输出:

评估仅位置参数: 
66

仅关键字参数

那些在调用函数时必须通过其名称来指定的参数被称为仅关键字参数。它们通过在函数的参数列表中关键字参数之前放置一个星号("*")来定义。这种类型的参数只能作为关键字参数而不是位置参数传递给函数。

示例

在下面的代码中,我们定义了一个带有三个仅关键字参数的函数。为了调用这个方法,我们需要传递关键字参数,否则我们将遇到一个错误。

def posFun(*, num1, num2, num3):
    print(num1 * num2 * num3)

print("评估仅关键字参数: ")
posFun(num1=6, num2=8, num3=5) 

它将产生如下的输出:

评估仅关键字参数: 
240

可变长参数或任意参数

您可能需要处理比在定义函数时所指定更多的参数。这些参数被称为可变长参数,并且不像必需参数和默认参数那样在函数定义中命名。

带有非关键字可变参数的函数的语法如下:

def functionname([形式参数,] *可变参数元组):
   "函数文档字符串"
   函数主体
   return [表达式]

在持有所有非关键字可变参数值的变量名前放置一个星号(*)。如果在函数调用中没有指定额外的参数,则这个元组将保持为空。

示例

下面是Python可变长参数的一个简单例子。

# 函数定义在这里
def printinfo(arg1, *vartuple):
   "这将在函数中打印可变传递的参数"
   print("输出是: ")
   print(arg1)
   for var in vartuple:
      print(var)
   return;

# 现在你可以调用printinfo函数
printinfo(10)
printinfo(70, 60, 50)

当上述代码被执行时,会产生如下的结果:

输出是:
10
输出是:
70
60
50

在接下来的章节中,我们将详细讨论这些函数参数。

Python函数参数的顺序

一个函数可以有上述定义的任何类型的参数。然而,参数必须按照以下顺序声明:

参数列表从仅位置参数开始,后面跟着斜杠(/)符号。

接着是常规的位置参数,可以作为关键字参数调用。

然后可能有一个或多个具有默认值的参数。

接下来是一个前面带单个星号的变量表示的任意位置参数,这被视为一个元组。

如果函数有任何仅关键字参数,则在其名称前放一个星号。一些仅关键字参数可能有一个默认值。

最后在括号里是带有双星号**的参数,用来接受任意数量的关键字参数。

下图显示了形式参数的顺序:

正式论证的顺序

返回值的Python函数

在函数定义中的最后一行使用return关键字表明了函数块的结束,并且程序流程返回到调用函数。尽管减少缩进也是隐式返回的一种方式,但显式使用return是一个好习惯。

除了控制流程外,函数还可以返回一个表达式的值给调用函数。返回表达式的值可以存储在一个变量中以便进一步处理。

示例

让我们定义add()函数。它将传递给它的两个值相加并返回它们的和。返回的值存储在一个名为result的变量中。

def add(x, y):
   z = x + y
   return z
a = 10
b = 20
result = add(a, b)
print("a = {} b = {} a+b = {}".format(a, b, result))

它将产生如下的输出:

a = 10 b = 20 a+b = 30

匿名函数

当函数不是使用def关键字以标准方式声明时,它们被称为匿名函数。相反,它们使用lambda关键字定义。

Lambda形式可以接受任意数量的参数,但只返回一个表达式的值。它们不能包含命令或多个表达式。

一个匿名函数不能直接调用print,因为lambda需要一个表达式。

Lambda函数有自己的局部命名空间,无法访问除了它们的参数列表之外的变量和全局命名空间中的变量。

尽管看起来lambda像是函数的一行版本,但它们并不等同于C或C++中的内联语句,后者的目的在于通过调用期间绕过函数栈分配来提高性能。

语法

Lambda函数的语法只包含单个语句,如下所示:

lambda [arg1 [,arg2,...argn]]: 表达式

示例

下面的例子展示了lambda形式的函数是如何工作的:

# 函数定义在这里
sum = lambda arg1, arg2: arg1 + arg2

# 现在你可以像调用函数一样调用sum
print("总值: ", sum(10, 20))
print("总值: ", sum(20, 20))

当上述代码被执行时,会产生如下的结果:

总值:  30
总值:  40

变量的作用域

程序中的所有变量可能不是在程序的所有位置都可以访问的。这取决于你在哪里声明了变量。

变量的作用域决定了程序中可以访问特定标识符的部分。Python中有两种基本的变量作用域:

  • 全局变量
  • 局部变量

全局变量与局部变量

在函数体内定义的变量具有局部作用域,而在函数体外定义的变量具有全局作用域。

这意味着局部变量只能在声明它们的函数内部访问,而全局变量可以在程序体内的所有函数中访问。当你调用一个函数时,声明在其中的变量进入作用域。

示例

下面是一个简单的局部和全局作用域的例子:

total = 0  # 这是一个全局变量。
# 函数定义在这里
def sum(arg1, arg2):
   # 将两个参数相加并返回它们。
   total = arg1 + arg2  # 这里的total是局部变量。
   print("函数内部的局部total: ", total)
   return total;

# 现在你可以调用sum函数
sum(10, 20)
print("函数外部的全局total: ", total)

当上述代码被执行时,会产生如下的结果:

函数内部的局部total:  30
函数外部的全局total:  0
 
上一章 下一章
阅读号二维码

关注阅读号

联系二维码

联系我们

© 2024 Yoagoa. All rights reserved.

粤ICP备18007391号

站点地图