Python青少年简明教程:函数

2024-09-03 01:44

本文主要是介绍Python青少年简明教程:函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Python青少年简明教程:函数

在Python中,函数是一段可重用的代码块,用于执行特定的任务。函数能够接受输入参数,执行特定的操作,并返回结果。

Python提供了许多内置函数,如print()、len()、eval()等,可以直接使用。编程人员还可以自定义函数。

先看几个内置函数,然后重点介绍编程人员自定义函数。

内置函数

Python 提供了许多内置函数,这些函数可以在任何 Python 程序中直接使用,不需要额外导入。下面介绍几个常用的内置函数。

1) len()函数

语法(用法):

len(object)

其中,object 是你想要获取长度的对象。

用途:返回对象的长度(元素个数)

适用于:字符串、列表、元组、字典等

示例:

print(len("Hello"))  # 输出:5
print(len([1, 2, 3]))  # 输出:3my_string = "Hello"
print(len(my_string))  # 输出 5

2) eval()函数

语法(用法):

eval(expression, globals=None, locals=None)

其中,expression 是一个字符串,必须是有效的 Python 表达式——能计算的字符串表达式。

globals(可选):一个字典,表示全局命名空间。

locals(可选):一个字典,表示局部命名空间。

示例:

x = 1
print(eval("x + 1"))  # 输出:2
result = eval("3 + 5")
print(result)  # 输出 8# 使用字典作为命名空间的例子:
globals_dict = {"a": 5, "b": 10}
result = eval("a + b", globals_dict)
print(result)  # 输出: 15

更多的情况可参见,内置函数官方文档内置函数 — Python 3.12.5 文档

下面介绍程序员自定义函数。

函数定义

编程人员还可以自定义函数。

使用 def 关键字定义函数,后跟函数名和括号(包含参数列表)。语法:

def函数名(参数列表):

    # 函数体

    return返回值

函数名:函数名可以是任何有效的标识符,但最好是有意义的名字,能反映出函数的功能。

参数列表:在圆括号中定义,用于接收传递给函数的值。多个参数用逗号分隔。参数是可选的,如果没有参数,圆括号内为空。

函数体:包含函数执行的操作或计算。

返回值:使用 return 语句返回结果给调用者。如果没有 return 语句,函数将返回 None。

函数调用

使用函数名后跟一对括号,括号中包含参数——如果有的话。

形参(形式参数,parameters)和实参(实际参数,arguments)

形参是指函数定义中使用的参数,它们相当于占位符,用于指定函数可以接受的输入。形参在函数定义时出现,用于接收函数调用时传入的实参。

实参是指在函数调用时传递给函数的具体值。实参在函数调用时出现,用于替换形参的值。

示例:

#定义add函数
def add(x, y):  
return x + y  result = add(5, 3)  # 调用函数,并接收返回值  
print(result)  # 输出:8

文档字符串

如果三重引号用放在函数、类或模块的开头,Python 会把它们当作文档字符串(docstring),这是一种特别的多行注释形式,用于生成文档,可以通过 __doc__ 属性 或 help(add) 函数查看。

def add(a, b):"""返回两个数的和。参数:a -- 第一个数b -- 第二个数"""return a + bprint(add.__doc__)  # 打印函数的文档字符串

在这个例子中,你可以通过 add.__doc__ 或 help(add) 来查看这个文档字符串的内容。

参数传递的内部机制

官方术语,参数传递使用按值调用(call by value)的方式(其中的值始终是对象的引用,而不是对象的值)。实际上,Python函数参数传递的始终对象的引用,而不是对象的值。这方面的内容,因一些人和资料介绍的比较混乱,特地附注。

【附注(有关官方文档节选):

The actual parameters (arguments) to a function call are introduced in the local symbol table of the called function when it is called; thus, arguments are passed using call by value (where the value is always an object reference, not the value of the object). [1] When a function calls another function, or calls itself recursively, a new local symbol table is created for that call.

https://docs.python.org/3/tutorial/controlflow.html#defining-functions

在调用函数时会将实际参数(实参)引入到被调用函数的局部符号表中;因此,实参是使用 按值调用 来传递的(其中的 值 始终是对象的 引用 而不是对象的值)。 [1] 当一个函数调用另外一个函数时,会为该调用创建一个新的局部符号表。

https://docs.python.org/zh-cn/3/tutorial/controlflow.html#defining-functions

Remember that arguments are passed by assignment in Python. Since assignment just creates references to objects, there’s no alias between an argument name in the caller and callee, and so no call-by-reference per se.

https://docs.python.org/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference

请记住,Python 中的实参是通过赋值传递的。由于赋值只是创建了对象的引用,所以调用方和被调用方的参数名都不存在别名,本质上也就不存在按引用调用的方式。

https://docs.python.org/zh-cn/3/faq/programming.html#how-do-i-write-a-function-with-output-parameters-call-by-reference】

这种机制有时也被一些人非正式称呼较多如“传递对象引用”(pass by object reference)、按对象引用调用(call by object reference),但机制本质不变。

对于不可变对象(如整数、字符串、元组),因为其不可变性,函数内对参数的任何修改不会影响到外部变量。对于可变对象(如列表、字典、集合),函数内对参数的修改会影响到外部变量。

a)如果传入的参数是不可变类型(如数字、字符串、元组),那么在函数体内修改参数的值,并不会影响到原来的变量。因为不可变类型的变量实际上是值的引用,当试图改变变量的值时,相当于是在创建新的对象。例如:

def change_number(num):num = 100x = 10
change_number(x)
print(x)  # 输出:10

在上面的例子中,尽管在函数内部num的值被改变了,但是原变量x的值并没有改变。参见下图:

b)如果传入的参数是可变类型(如列表、字典),那么在函数体内修改参数的值,会影响到原来的变量。因为可变类型的变量存储的是一个地址,当试图改变变量的值时,实际上是在改变这个地址所指向的内容。例如:

def change_list(lst):lst.append(100)x = [1, 2, 3]
change_list(x)
print(x)  # 输出:[1, 2, 3, 100]

在上面的例子中,函数内部对参数lst的修改影响到了原变量x的值。参见下图:

从内存管理的角度来看,Python中的变量和参数传递有一些特点

☆ 变量是对象的引用:在Python中,变量实际上是对象的引用,而不是对象本身。当你给一个变量赋值时,实际上是将变量指向了一个对象。这意味着变量可以指向不同类型的对象,并且可以在程序中随时改变指向的对象。

☆ 引用计数:Python使用引用计数来管理内存。每个对象都有一个引用计数,表示有多少个变量引用了该对象。当引用计数为0时,对象将被自动回收。当一个变量不再引用一个对象时,引用计数会减少。当引用计数为0时,对象的内存将被释放。

☆ 对象的可变性:Python中的对象分为可变对象和不可变对象。可变对象(如列表、字典)的值可以被修改,而不可变对象(如整数、字符串、元组)的值不能被修改。这意味着如果你修改了一个可变对象,那么所有引用这个对象的变量都会受到影响。

☆ 参数传递方式:在Python中,函数的参数传递是按值调用(call by value) 来传递的(其中的 值 始终是对象的 引用 而不是对象的值)——实际上,按对象引用调用(call by object reference)调用这种说法更好。对于不可变对象(如整数、字符串、元组),由于它们的值不能被改变,所以函数内部对这些对象的修改实际上是创建了一个新的对象。因此,函数内部的修改不会影响到函数外部的实际参数。对于可变对象(如列表、字典),由于它们的值可以被改变,所以函数内部对这些对象的修改会直接改变原始对象的值。因此,函数内部的修改会影响到函数外部的实际参数。

【附、Python语言的变量和参数传递情况https://blog.csdn.net/cnds123/article/details/134159800

多种(C++、Java、JavaScript、Python)编程语言参数传递方式介绍https://blog.csdn.net/cnds123/article/details/132981086 】

参数情况说明

☆位置参数(Positional Arguments)

位置参数是最基本的参数传递方式,按照参数在函数定义中的位置传递。例如:

def add(a, b):return a + bresult = add(3, 5)  # 位置参数,3 传给 a,5 传给 b
print(result)  # 输出 8

☆关键字参数(Keyword Arguments)

关键字参数通过参数名传递,可以不按照定义时的顺序传递。例如:

def greet(name, msg):print(f"{msg}, {name}!")greet(name="Alice", msg="Hello")  # 关键字参数
greet(msg="Hi", name="Bob")  # 顺序可以不同

☆默认参数(Default Arguments)

默认参数在函数定义时指定了默认值,如果调用函数时没有提供该参数,则使用默认值。例如:

def greet(name, msg="Hello"):print(f"{msg}, {name}!")greet("Alice")  # 使用默认参数,输出 "Hello, Alice!"
greet("Bob", "Hi")  # 覆盖默认参数,输出 "Hi, Bob!"

☆可变参数(Variable-length Arguments)

Python 支持可变数量的参数,使用 *args 和 **kwargs。

1) *args 用于传递任意数量的位置参数,接收的是一个元组。例如:

def print_numbers(*args):for num in args:print(num)print_numbers(1, 2, 3, 4)  # 输出 1 2 3 4

2)不定长关键字参数(**kwargs)

**kwargs 用于传递任意数量的关键字参数,接收的是一个字典。例如:

def print_info(**kwargs):for key, value in kwargs.items():print(f"{key}: {value}")print_info(name="Alice", age=25)  # 输出 "name: Alice" "age: 25"

☆在 Python 3.8 及以后的版本中,函数参数传递机制中引入了两个新的语法元素:/ 和 *,它们用来指定参数的类型,即位置参数、关键字参数以及两者混合的参数。

1)仅限位置参数(Positional-only Parameters)

使用 / 将参数标记为仅限位置参数。这意味着这些参数必须通过位置进行传递,不能使用关键字来传递。例如:

def func(a, b, /, c, d):print(a, b, c, d)func(1, 2, 3, 4)  # 正确
func(1, 2, c=3, d=4)  # 错误,会引发 TypeError

在这个例子中,a 和 b 必须通过位置传递,而 c 和 d 可以通过位置或关键字传递。

2)仅限关键字参数(Keyword-only Parameters)

使用 * 将参数标记为仅限关键字参数。这意味着这些参数必须通过关键字传递。例如:

def func(a, b, *, c, d):print(a, b, c, d)func(1, 2, c=3, d=4)  # 正确
func(1, 2, 3, 4)  # 错误,会引发 TypeError

在这个例子中,c 和 d 必须通过关键字传递,而 a 和 b 可以通过位置或关键字传递。

3)同时使用 / 和 *

在函数定义中可以同时使用 / 和 *,以指定不同类型的参数。例如:

def func(a, b, /, c, *, d):print(a, b, c, d)func(1, 2, 3, d=4)  # 正确
func(1, 2, c=3, d=4)  # 正确
func(1, 2, 3, 4)  # 错误,会引发 TypeError
func(a=1, b=2, c=3, d=4)  # 错误,会引发 TypeError

在这个例子中,a 和 b 必须通过位置传递,c 可以通过位置或关键字传递,d 必须通过关键字传递。

☆参数解包

Python 支持参数解包(unpacking),这是一种将容器(如列表、元组或字典)中的元素解包并传递给函数参数的方式。参数解包可以通过 * 和 ** 实现。

1)使用 * 解包列表或元组

当你有一个包含多个元素的列表或元组,并且你希望将这些元素作为单独的参数传递给函数时,可以使用 * 进行解包。例如:

def add(a, b, c):return a + b + cnumbers = [1, 2, 3]
result = add(*numbers)  # 等同于 add(1, 2, 3)
print(result)  # 输出 6values = (4, 5, 6)
result = add(*values)  # 等同于 add(4, 5, 6)
print(result)  # 输出 15

2) 使用 ** 解包字典

当你有一个字典,并且字典的键与函数参数名匹配时,可以使用 ** 进行解包,将字典中的键值对作为关键字参数传递给函数。例如:

def greet(name, greeting, punctuation):print(f"{greeting}, {name}{punctuation}")params = {'name': 'Alice', 'greeting': 'Hello', 'punctuation': '!'}
greet(**params)  # 等同于 greet(name='Alice', greeting='Hello', punctuation='!')

变量作用域(scope

Python 中的作用域(scope)是指变量的可访问范围。Python 主要有以下几种作用域:

☆全局作用域(Global)

全局变量在函数外部定义,全局作用域是在整个程序(模块或脚本文件)中都可以访问的变量。例如:

global_var = "I'm global"def access_global():print(global_var)access_global()  # 输出: I'm global
print(global_var)  # 输出: I'm global

☆局部作用域(Local)

局部作用域指的是在函数内部定义的变量,只在函数内部可见。例如:

def local_scope_example():x = "local"print(x)local_scope_example()  # 输出: local
# print(x)  # 这会引发 NameError,因为 x 只在函数内部定义

☆闭包函数外的函数中(Enclosing)

这指的是嵌套函数中外层函数的作用域。例如:

def outer_function():x = "outer"def inner_function():print(x)  # 可以访问外层函数的变量inner_function()outer_function()  # 输出: outer

☆内置作用域(Built-in)

这是 Python 内置的名字空间,包含了内置函数和异常名称。例如:

print(len("Python"))  # 使用内置函数 len(),输出: 6

变量查找顺序

Python 按照 LEGB规则顺序查找变量:Local → Enclosing → Global → Built-in。

例如:

x = "global"def outer():x = "outer"def inner():x = "inner"print("inner:", x)inner()print("outer:", x)outer()
print("global:", x)# 输出:
# inner: inner
# outer: outer
# global: global

特别提示:

1) global 关键字

如果你想在函数内部修改全局变量,需要使用 global 关键字。例如:

count = 0def increment():global countcount += 1print(count)increment()  # 输出: 1
increment()  # 输出: 2

2) nonlocal 关键字

在嵌套函数中,如果要修改外层函数的变量,需要使用 nonlocal 关键字。例如:

def outer():x = 0def inner():nonlocal xx += 1print(x)return innercounter = outer()
counter()  # 输出: 1
counter()  # 输出: 2

理解 Python 的作用域规则对于编写清晰、可维护的代码非常重要。它可以帮助你避免命名冲突,更好地组织代码结构,并理解变量在不同上下文中的行为。

递归函数

函数调用自身的函数。需要有基本情况来结束递归。

递归是一种强大的编程技术,它允许函数调用自身来解决问题。

递归的基本概念:

递归函数是在其定义中直接或间接调用自身的函数。它通常用于解决可以被分解成相似的子问题的问题。

递归函数的结构:

一个典型的递归函数包含两个主要部分:

基本情况(Base case):不再递归调用的条件,用于终止递归。

递归情况(Recursive case):函数调用自身的部分。

示例1 - 计算阶乘

阶乘是最经典的递归函数之一。数学上,n 的阶乘(n!)定义为:

0! = 1

n! = n * (n-1)!,当n > 0时

源码如下:

def factorial(n):# 基准情况:当 n 为 0 时,返回 1if n == 0:return 1# 递归情况:n * (n-1) 的阶乘else:return n * factorial(n - 1)print(factorial(5))  # 输出: 120

解释:

factorial(0) 返回 1(基准情况)。

factorial(n) 对于 n > 0,会递归调用 factorial(n - 1)。

计算 factorial(5) 的过程如下:

factorial(5) = 5 * factorial(4)

factorial(4) = 4 * factorial(3)

factorial(3) = 3 * factorial(2)

factorial(2) = 2 * factorial(1)

factorial(1) = 1 * factorial(0)

factorial(0) = 1(基准情况)

递归调用结束并逐步回溯,最终计算出结果 5! = 120。

匿名函数(Lambda函数)

在 Python 中,匿名函数(Anonymous Function)指的是没有名字的函数,通常使用 lambda 关键字来定义。匿名函数通常用于需要一个简单函数且只使用一次的场景。

名函数的语法非常简洁,使用 lambda 关键字定义,语法格式如下:

lambda 参数1, 参数2, ... : 表达式

lambda 是关键字,表示这是一个匿名函数。

参数1, 参数2, ... 是函数的参数,多个参数用逗号分隔。

表达式 是函数体,只能是一个表达式,计算结果就是这个函数的返回值。匿名函数的结果会自动返回,无需使用 return 关键字。

简单的匿名函数示例

一个简单的匿名函数,计算两个数的和:

add = lambda x, y: x + y

这个 lambda 表达式定义了一个匿名函数,并将其赋值给 add 变量。add 现在可以像普通函数一样使用:

result = add(3, 5)
print(result)  # 输出: 8

与普通函数的对比

匿名函数和普通函数(使用 def 关键字定义的函数)的主要区别在于匿名函数更适合定义简单的、一次性的函数。普通函数适用于更复杂的逻辑或者需要多次使用的情况下。

普通函数:

def add(x, y):return x + yresult = add(3, 5)
print(result)  # 输出: 8

匿名函数可写为:

add = lambda x, y: x + y
result = add(3, 5)
print(result)  # 输出: 8

在这个简单的例子中,匿名函数和普通函数的效果是一样的,但匿名函数更加简洁。

在使用像 map()、filter()、sorted()、reduce() 等高阶函数时,经常会用到匿名函数。关于高阶函数就不多说了。

这篇关于Python青少年简明教程:函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1131671

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

nudepy,一个有趣的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - nudepy。 Github地址:https://github.com/hhatto/nude.py 在图像处理和计算机视觉应用中,检测图像中的不适当内容(例如裸露图像)是一个重要的任务。nudepy 是一个基于 Python 的库,专门用于检测图像中的不适当内容。该

SWAP作物生长模型安装教程、数据制备、敏感性分析、气候变化影响、R模型敏感性分析与贝叶斯优化、Fortran源代码分析、气候数据降尺度与变化影响分析

查看原文>>>全流程SWAP农业模型数据制备、敏感性分析及气候变化影响实践技术应用 SWAP模型是由荷兰瓦赫宁根大学开发的先进农作物模型,它综合考虑了土壤-水分-大气以及植被间的相互作用;是一种描述作物生长过程的一种机理性作物生长模型。它不但运用Richard方程,使其能够精确的模拟土壤中水分的运动,而且耦合了WOFOST作物模型使作物的生长描述更为科学。 本文让更多的科研人员和农业工作者

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip