网站如何自己做seo/网络营销ppt

网站如何自己做seo,网络营销ppt,苏州做网站比较好的公司,文档做网站欢迎来到ZyyOvO的博客✨,一个关于探索技术的角落,记录学习的点滴📖,分享实用的技巧🛠️,偶尔还有一些奇思妙想💡 本文由ZyyOvO原创✍️,感谢支持❤️!请尊重原创&#x1…

欢迎来到ZyyOvO的博客✨,一个关于探索技术的角落,记录学习的点滴📖,分享实用的技巧🛠️,偶尔还有一些奇思妙想💡
本文由ZyyOvO原创✍️,感谢支持❤️!请尊重原创📩!欢迎评论区留言交流🌟
个人主页 👉 ZyyOvO
本文专栏➡️Python 算法研究所

请添加图片描述

快速复习👉【Python 速览 】 —— 课前甜点,打开你的味蕾

课前导入

我们知道数学中的函数,我们输入一个数,在通过对应的映射关系得到另一个数,如下图给出了两个简单的数学函数:
在这里插入图片描述

什么是函数

那在Python编程中函数是什么呢?

在编程中,函数(Function) 是一段被命名、可重复使用的代码块,用于执行特定任务,它通过接收输入(参数),处理逻辑,并返回输出(结果),将复杂的程序拆分为模块化的组件,让代码更简洁、高效且易于维护。

函数的优势

在 Python 中,函数是编程的核心工具之一,它通过将代码逻辑封装为可重复使用的模块,显著提升了代码的可维护性、复用性和可读性。

避免代码重复:DRY 原则(Don't Repeat Yourself)

  • 问题场景: 当同一段代码需要多次使用时,复制粘贴会导致代码臃肿,且后续修改需要逐一调整所有副本。
  • 函数解决方案: 将重复代码封装为函数,通过一次定义、多次调用来实现逻辑复用。
# 重复代码示例(计算圆面积)
radius1 = 5
area1 = 3.14 * radius1 ** 2radius2 = 7
area2 = 3.14 * radius2 ** 2# 使用函数优化
def calculate_circle_area(radius):return 3.14 * radius ** 2area1 = calculate_circle_area(5)
area2 = calculate_circle_area(7)
  • 修改逻辑只需调整函数内部代码(例如将 3.14 改为 math.pi)。
  • 减少代码量,避免冗余。

模块化编程:分解复杂问题

  • 问题场景: 一个大型程序如果写成连续的代码块,会难以理解和维护。
  • 函数解决方案: 将程序拆分为多个函数,每个函数负责单一职责。
# 未使用函数的复杂逻辑
data = [1, 2, 3, 4, 5]
sum = 0
for num in data:sum += num
average = sum / len(data)
print(f"平均值: {average}")# 使用函数模块化
def calculate_average(data):return sum(data) / len(data)data = [1, 2, 3, 4, 5]
print(f"平均值: {calculate_average(data)}")
  • 代码逻辑清晰,每个函数聚焦一个子任务。
  • 便于团队协作开发。

提升代码可读性

  • 问题场景: 长段代码缺乏注释时,阅读者需要逐行理解逻辑。
  • 函数解决方案: 通过函数名称直接表明代码意图。
# 难读的代码
x = 5
y = 10
result = (x ** 2 + y ** 2) ** 0.5# 使用函数自解释
def calculate_hypotenuse(a, b):return (a**2 + b**2) ** 0.5result = calculate_hypotenuse(5, 10)
  • 函数名(如 calculate_hypotenuse)直接说明功能。
  • 减少对注释的依赖。

参数化与灵活性

  • 问题场景: 相似逻辑需要处理不同输入数据时,硬编码值会限制灵活性。
  • 函数解决方案: 通过参数动态接收输入,返回处理结果。
# 硬编码的欢迎语
print("欢迎,张三!")
print("欢迎,李四!")# 参数化函数
def greet(name):print(f"欢迎,{name}!")greet("张三")
greet("李四")
  • 同一函数适应不同输入。
  • 支持动态数据处理。

错误隔离与调试效率

  • 问题场景: 代码错误可能出现在任意位置,调试时需全局排查。
  • 函数解决方案: 将代码划分为函数后,错误通常能被隔离到特定函数内。
def load_data(filename):# 假设此处可能抛出文件不存在的错误with open(filename, 'r') as f:return f.read()def process_data(data):# 此处可能处理数据时出错return data.upper()try:data = load_data("data.txt")result = process_data(data)
except Exception as e:print(f"错误发生在: {e}")
  • 快速定位问题函数。
  • 通过单元测试单独验证每个函数。

支持代码复用与库开发

  • 问题场景: 通用功能(如数据验证、数学计算)需要在多个项目中重复实现。
  • 函数解决方案: 将通用函数封装为模块(.py 文件),供其他程序导入。
# utils.py
def is_prime(n):if n <= 1:return Falsefor i in range(2, int(n**0.5)+1):if n % i == 0:return Falsereturn True# main.py
from utils import is_prime
print(is_prime(17))  # 输出: True
  • 积累个人代码库,提升开发效率。
  • 促进开源社区协作(如 numpyrequests 等库)。

实现递归算法

  • 问题场景: 某些问题(如阶乘、斐波那契数列)天然适合递归解决。
  • 函数解决方案: 函数可以调用自身,简化递归逻辑。
def factorial(n):if n == 0:return 1else:return n * factorial(n-1)print(factorial(5))  # 输出: 120
  • 以简洁方式解决复杂递归问题。
  • 代码更接近数学定义。
应用场景函数的核心作用
代码重复封装重复逻辑,实现 DRY 原则
复杂问题分解为模块化组件,降低认知负担
可读性差通过命名自解释代码意图
动态数据处理参数化输入,提升灵活性
错误调试隔离问题范围,简化排查流程
代码复用构建可共享的代码库
递归问题实现自我调用的算法逻辑

通过函数,Python 代码从“一次性脚本”升级为可维护、可扩展的工程化项目。它是构建大型应用、开源库和高效算法的基石。


定义函数

例如,我们写一段代码来求斐波那契数列:

def fib(n):    # 打印小于 n 的斐波那契数列"""Print a Fibonacci series less than n."""a, b = 0, 1while a < n:print(a, end=' ')a, b = b, a+b

定义 函数使用关键字 def,后跟函数名与括号内的形参列表。函数语句从下一行开始,并且必须缩进

函数内的第一条语句是字符串时,该字符串就是文档字符串,也称为 docstring。Python 开发者最好养成在代码中加入文档字符串的好习惯。

函数在 执行 时使用函数局部变量符号表,所有函数变量赋值都存在局部符号表中;引用变量时,首先,在局部符号表里查找变量,然后,是外层函数局部符号表,再是全局符号表,最后是内置名称符号表。因此,尽管可以引用全局变量和外层函数的变量,但最好不要在函数内直接赋值(除非是 global 语句定义的全局变量,或 nonlocal 语句定义的外层函数变量)。


函数对象的概念

在这里插入图片描述

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

在Python中遵循着一切皆对象的原则,无论是变量,函数,亦或是类,在Python看来都是对象,因此,函数定义在当前符号表中把函数名与函数对象关联在一起。解释器把函数名指向的对象作为用户自定义函数。
还可以使用其他名称指向同一个函数对象,并访问访该函数,例如我们上面写的求斐波那契数列的函数:

def fib(n):    # 打印小于 n 的斐波那契数列"""Print a Fibonacci series less than n."""a, b = 0, 1while a < n:print(a, end=' ')a, b = b, a+bf = fib #将函数对象赋值给ff(100) #调用f
print()
fib(100) #调用fib()

输出:

0 1 1 2 3 5 8 13 21 34 55 89 
0 1 1 2 3 5 8 13 21 34 55 89 

如果你学过其他语言,比如C语言或者C++,你可能会认为 fib 不是函数而是一个过程语句,因为它没有返回值。 事实上,即使没有 return 语句的函数也有返回值, 这个值被称为 None (是一个内置名称,Python中函数的默认返回值)。 通常解释器会屏蔽单独的返回值 None。 如果你确有需要可以使用 print() 查看它:

print(fib(0))
#输出
None

编写不直接输出斐波那契数列运算结果,而是返回运算结果列表的函数也非常简单:只需要在函数中定义列表,将斐波那契数使用append接口加入到列表中,最后返回列表对象即可:

def fib2(n):  # 返回斐波那契数组直到 n"""Return a list containing the Fibonacci series up to n."""result = []a, b = 0, 1while a < n:result.append(a)    # 见下a, b = b, a+breturn resultf100 = fib2(100)    # 调用它
f100                # 输出结果
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

函数定义详解

函数定义支持可变数量的参数。这里列出三种可以组合使用的形式。

默认值参数

为参数指定默认值是非常有用的方式。调用函数时,可以使用比定义时更少的参数,例如:

def ask_ok(prompt, retries=4, reminder='Please try again!'):while True:reply = input(prompt)if reply in {'y', 'ye', 'yes'}:return Trueif reply in {'n', 'no', 'nop', 'nope'}:return Falseretries = retries - 1if retries < 0:raise ValueError('invalid user response')print(reminder)

该函数有三种调用方式:

  • 只给出必选实参:ask_ok('Do you really want to quit?')
  • 给出一个可选实参:ask_ok('OK to overwrite the file?', 2)
  • 给出所有实参:
ask_ok('OK to overwrite the file?', 2, 'Come on, only yes orno!')

retriesreminder默认参数。默认参数在函数定义时指定了默认值,调用函数时如果没有为这些参数提供值,就会使用默认值。而prompt位置参数,调用函数时必须按照顺序传递参数,否则就会导致错误!

使用示例:

try:#异常捕获result = ask_ok("Do you want to continue? ")if result:print("You agreed!")else:print("You disagreed!")
except ValueError as e:print(e)

默认值在 定义 作用域里的函数定义中求值 所以:

i = 5def f(arg=i):print(arg)i = 6
f()

上例输出的是 5。为什么呢???
这里创建了一个全局变量 i,并将其赋值为 5。在定义函数 f 时,默认参数 arg 的值被设定为当前全局变量 i 的值,也就是 5。需要注意的是,Python 函数的默认参数值是在函数定义时就确定下来的,而不是在函数调用时确定。

将全局变量 i 的值修改为 6,但这并不会影响函数 f 中默认参数 arg 的值,因为 arg 的默认值在函数定义时就已经确定为 5 了。

值得注意的是: 默认值只计算一次。默认值为列表、字典或类实例等可变对象时,会产生与该规则不同的结果。例如,下面的函数会累积后续调用时传递的参数:

def f(a, L=[]):L.append(a)return Lprint(f(1))
print(f(2))
print(f(3))

输出结果如下:

[1]
[1, 2]
[1, 2, 3]

这里定义了函数 f,其中参数 L 的默认值是一个空列表 []。需要特别注意的是,在 Python 中,函数的默认参数是在函数定义时就被创建的,并且只创建一次。也就是说,无论函数被调用多少次,这个默认的列表 L 始终是同一个对象

如果不想在后续调用之间共享默认值时,应以如下方式编写函数:

def f(a, L=None):if L is None:L = []L.append(a)return L

这样修改后,每次调用函数时,如果没有传入 L 参数,都会创建一个新的空列表,输出结果将分别为:

[1]
[2]
[3]

关键字参数

key=value 形式的 关键字参数 也可以用于调用函数。函数示例如下:

def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'):print("-- This parrot wouldn't", action, end=' ')print("if you put", voltage, "volts through it.")print("-- Lovely plumage, the", type)print("-- It's", state, "!")

该函数接受一个必选参数(voltage)和三个可选参数(state, action 和 type)。该函数可用下列方式调用:

parrot(1000)                                          # 1 个位置参数
parrot(voltage=1000)                                  # 1 个关键字参数
parrot(voltage=1000000, action='VOOOOOM')             # 2 个关键字参数
parrot(action='VOOOOOM', voltage=1000000)             # 2 个关键字参数
parrot('a million', 'bereft of life', 'jump')         # 3 个位置参数
parrot('a thousand', state='pushing up the daisies')  # 1 个位置参数,1 个关键字参数

以下调用函数的方式都无效:

parrot()                     # 缺失必需的参数
parrot(voltage=5.0, 'dead')  # 关键字参数后存在非关键字参数
parrot(110, voltage=220)     # 同一个参数重复的值
parrot(actor='John Cleese')  # 未知的关键字参数

函数调用时,关键字参数必须跟在位置参数后面.

例如,以下调用方式是错误的:

# 错误示例,位置参数应在关键字参数之前
parrot(state='dead', 300)

所有传递的关键字参数都必须匹配一个函数接受的参数(比如,actor 不是函数 parrot 的有效参数),关键字参数的顺序并不重要。这也包括必选参数,(比如,parrot(voltage=1000) 也有效)。不能对同一个参数多次赋值,下面就是一个因此限制而失败的例子:

def function(a):passfunction(0, a=0)

最后一个形参为 **name 形式时,接收一个字典,(映射类型 — dict),该字典包含与函数中已定义形参对应之外的所有关键字参数。**name 形参可以与 *name 形参(下一小节介绍)组合使用(*name 必须在 **name 前面), *name 形参接收一个 元组,该元组包含形参列表之外的位置参数。例如,可以定义下面这样的函数:

def cheeseshop(kind, *arguments, **keywords):print("-- Do you have any", kind, "?")print("-- I'm sorry, we're all out of", kind)for arg in arguments:print(arg)print("-" * 40)for kw in keywords:print(kw, ":", keywords[kw])

参数解释:

  • kind:这是一个普通的位置参数,调用函数时必须提供该参数的值,用于指定奶酪的种类。
  • *arguments:这是一个可变位置参数,它会将函数调用时传入的除了第一个位置参数(即 kind)之外的所有位置参数收集到一个元组中。在函数内部,可以通过遍历这个元组来处理这些参数。
  • **keywords:这是一个可变关键字参数,它会将函数调用时传入的所有未在函数定义中明确指定的关键字参数收集到一个字典中。字典的键是关键字参数的名称,值是对应的参数值。

该函数可以用如下方式调用:

cheeseshop("Limburger", "It's very runny, sir.","It's really very, VERY runny, sir.",shopkeeper="Michael Palin",client="John Cleese",sketch="Cheese Shop Sketch")

第一个参数 "Limburger" 被赋值给 kind
接下来的两个字符串 "It's very runny, sir.""It's really very, VERY runny, sir." 被收集到 arguments 元组中。
最后三个关键字参数 shopkeeper="Michael Palin"、client="John Cleese"sketch="Cheese Shop Sketch" 被收集到 keywords 字典中。

输出结果如下:

-- Do you have any Limburger ?
-- I'm sorry, we're all out of Limburger
It's very runny, sir.
It's really very, VERY runny, sir.
----------------------------------------
shopkeeper : Michael Palin
client : John Cleese
sketch : Cheese Shop Sketch

在 Python 中,*arguments(可变位置参数)必须放在 **keywords(可变关键字参数)之前,否则会导致语法错误,为什么呢???

Python 函数在调用时,会按照特定的顺序解析传入的参数,具体顺序为:

位置参数 -> 可变位置参数 -> 关键字参数 -> 可变关键字参数。
  • 位置参数:是按照参数定义的顺序依次接收传入的值。
  • 可变位置参数:会收集所有剩余的位置参数(即除了已被普通位置参数接收的部分)到一个元组中。
  • 关键字参数:通过参数名来指定传入的值。
  • 可变关键字参数:会收集所有未在函数定义中明确指定的关键字参数到一个字典中。

如果 **keywords 放在 *arguments 之前,当函数调用时,Python 解释器在解析参数时就会遇到问题。因为 **keywords 会优先收集所有的关键字参数,而此时如果还有剩余的位置参数,就无法正确地将它们收集到 *arguments 中,因为 *arguments 是用来收集位置参数的,而在 **keywords 之后,解释器已经无法区分哪些是位置参数了。

注意,关键字参数在输出结果中的顺序与调用函数时的顺序一致。


特殊参数

默认情况下,参数可以按位置或显式关键字传递给 Python 函数。为了让代码易读、高效,最好限制参数的传递方式,这样,开发者只需查看函数定义,即可确定参数项是仅按位置、按位置或关键字,还是仅按关键字传递。

函数定义如下:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):-----------    ----------     ----------|             |                  ||        位置或关键字   ||                                - 仅限关键字-- 仅限位置

/ 和 * 是可选的。这些符号表明形参如何把参数值传递给函数:位置、位置或关键字、关键字。关键字形参也叫作命名形参。

位置或关键字参数

函数定义中未使用 /* 时,参数可以按位置或关键字传递给函数。

仅位置参数

此处再介绍一些细节,特定形参可以标记为 仅限位置。仅限位置 时,形参的顺序很重要,且这些形参不能用关键字传递。仅限位置形参应放在 / (正斜杠)前。/ 用于在逻辑上分割仅限位置形参与其它形参。如果函数定义中没有 /,则表示没有仅限位置形参。
/ 后可以是 位置或关键字 或 仅限关键字 形参。

仅限关键字参数

把形参标记为 仅限关键字,表明必须以关键字参数形式传递该形参,应在参数列表中第一个 仅限关键字 形参前添加 *

简单的函数示例

注意 / 和 * 标记:

def standard_arg(arg):print(arg)def pos_only_arg(arg, /):print(arg)def kwd_only_arg(*, arg):print(arg)def combined_example(pos_only, /, standard, *, kwd_only):print(pos_only, standard, kwd_only)

第一个函数定义 standard_arg 是最常见的形式,对调用方式没有任何限制,可以按位置也可以按关键字传递参数:

位置参数:

standard_arg(2)
#输出
2

关键字参数:

standard_arg(arg=2)
#输出
2

第二个函数 pos_only_arg 的函数定义中有 /,仅限使用位置形参

位置形参:

pos_only_arg(1)
#输出
1

关键字参数:报错!

pos_only_arg(arg=1)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: pos_only_arg() got some positional-only arguments passed as keyword arguments: 'arg'

第三个函数 kwd_only_arg 如在函数定义中通过 * 所指明的那样只允许关键字参数。

位置参数:报错

kwd_only_arg(3)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: kwd_only_arg() takes 0 positional arguments but 1 was given

关键字参数:

kwd_only_arg(arg=3)
#输出
3

最后一个函数在同一个函数定义中,使用了全部三种调用惯例:

全部位置参数:报错!

combined_example(1, 2, 3)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: combined_example() takes 2 positional arguments but 3 were given

位置参数和关键字参数:

combined_example(1, 2, kwd_only=3)
#输出
1 2 3combined_example(1, standard=2, kwd_only=3)
#输出
1 2 3

全部关键字参数:报错!

combined_example(pos_only=1, standard=2, kwd_only=3)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: combined_example() got some positional-only arguments passed as keyword arguments: 'pos_only'

下面的函数定义中,kwdsname 当作键,因此,可能与位置参数 name 产生潜在冲突:

def foo(name, **kwds):return 'name' in kwds

调用该函数不可能返回 True,因为关键字 'name' 总与第一个形参绑定。例如:

foo(1, **{'name': 2})
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: foo() got multiple values for argument 'name'

代码报错原因:

当执行 foo(1, **{'name': 2}) 时:
首先,Python 会把位置参数 1 赋值给 name,这是按照位置参数的传递规则来的。
接着,要把字典 {'name': 2} 解包传递给函数。但是这时 Python 发现,name 这个参数已经被位置参数 1 赋值过了,现在又有一个关键字参数 name=2 要进来,就会产生冲突。因为在 Python 里,一个参数不能被多次赋值,所以就会抛出 TypeError: foo() got multiple values for argument 'name' 异常。

正确做法:

  • 加上 / (仅限位置参数)后,就可以了。此时,函数定义把 name 当作位置参数,'name' 也可以作为关键字参数的键:
def foo(name, /, **kwds):return 'name' in kwdsfoo(1, **{'name': 2})
#输出
True
  • 这里的 / 起到了关键作用,它把 name 变成了仅限位置参数。这就规定了 name
    只能通过位置的方式来传值,不能用关键字参数的方式传值。

调用过程分析
当调用 foo(1, **{'name': 2}) 时:
位置参数 1 会被正常赋值给仅限位置参数 name,这是符合仅限位置参数的传递规则的。
对于字典 {'name': 2},由于 name 是仅限位置参数,字典里的 'name' 键就不会和函数定义里的 name 参数冲突了。**kwds 会把这个 {'name': 2} 字典收集起来,成为一个包含 'name': 2 的字典。
函数内部的 'name' in kwds 语句会去检查 'name' 这个键是否在 kwds 字典里,因为 kwds 字典里确实有 'name' 键,所以函数就会返回 True

可以把这种情况想象成有两个不同的 “区域”,一个区域(仅限位置参数 name)只能通过位置传递的方式放东西进去;另一个区域(**kwds 字典)可以接收关键字参数。这样就避免了参数名的冲突。

换句话说,仅限位置形参的名称可以在 **kwds 中使用,而不产生歧义。

小结

以下用例决定哪些形参可以用于函数定义:

def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):

说明:

  • 使用仅限位置形参,可以让用户无法使用形参名。形参名没有实际意义时,强制调用函数的实参顺序时,或同时接收位置形参和关键字时,这种方式很有用。
  • 当形参名有实际意义,且显式名称可以让函数定义更易理解时,阻止用户依赖传递实参的位置时,才使用关键字。
  • 对于 API,使用仅限位置形参,可以防止未来修改形参名时造成破坏性的 API 变动。

函数的变量

变量的作用域

在这里插入图片描述

在 Python 中,作用域定义了变量和函数的可见性与生命周期,它决定了在程序的哪些部分可以访问特定的变量或函数。Python 中有四种主要的作用域,按照搜索变量的顺序依次为:局部作用域(Local)闭包作用域(Enclosing)全局作用域(Global)内置作用域(Built-in),通常用 LEGB 规则来描述这个搜索顺序。下面为你详细介绍这四种作用域。

内置作用域(Built-in)

定义:内置作用域是 Python 预先定义好的,包含了所有内置的函数、异常和对象,如 print()len()int 等。这些名称在整个 Python 程序中都是可用的,无需额外导入。
示例:

# 直接使用内置函数 print 和 len
print(len([1, 2, 3]))

在这个例子中,printlen 都是内置作用域中的函数,可以直接使用。


全局作用域(Global)

定义:全局作用域是在整个模块(即 .py 文件)中定义的作用域。在模块顶层定义的变量和函数都属于全局作用域,它们可以在模块的任何地方被访问,但在函数内部如果要修改全局变量,需要使用 global 关键字。
示例:

# 定义全局变量
global_variable = 10def print_global_variable():# 可以在函数内部访问全局变量print(global_variable)print_global_variable()  # 输出: 10def modify_global_variable():global global_variableglobal_variable = 20modify_global_variable()
print(global_variable)  # 输出: 20

在上述代码中,global_variable 是全局变量,可以在函数 print_global_variable 中直接访问。而在 modify_global_variable 函数中,如果要修改全局变量的值,需要使用 global 关键字声明。

闭包作用域(Enclosing)

定义:闭包作用域也称为嵌套作用域,它出现在嵌套函数中。当一个函数内部定义了另一个函数时,内部函数可以访问外部函数的局部变量,这些外部函数的局部变量就处于闭包作用域中。在 Python 中,闭包是一种特殊的对象,它可以捕获并保存外部函数的局部变量状态。
示例:

def outer_function():enclosing_variable = 5def inner_function():# 内部函数可以访问外部函数的局部变量print(enclosing_variable)return inner_functionclosure = outer_function()
closure()  # 输出: 5

在这个例子中,inner_function 是嵌套在 outer_function 内部的函数,enclosing_variable 是 outer_function 的局部变量,对于 inner_function 来说,它处于闭包作用域中,因此 inner_function 可以访问这个变量。

局部作用域(Local)

定义:局部作用域是在函数内部定义的作用域。函数内部定义的变量和参数都属于局部作用域,它们只能在函数内部被访问,函数执行结束后,局部变量会被销毁。
示例:

def local_scope_example():local_variable = 3print(local_variable)local_scope_example()  # 输出: 3
# print(local_variable)  # 会报错,因为 local_variable 是局部变量,外部无法访问

local_scope_example 函数内部定义的 local_variable 是局部变量,只能在函数内部访问,在函数外部尝试访问会引发 NameError 异常。


函数中变量的查找顺序

在这里插入图片描述
在 Python 中,函数内部的变量查找遵循 LEGB 规则,即按照以下顺序逐层查找变量:
LEGB

Local(局部作用域) → Enclosing(闭包外层) → Global(全局) → Built-in(内置)
  1. Local(局部作用域)

优先级最高:首先在函数内部查找变量

示例:

def func():x = 10        # 局部变量print(x)      # 输出 10(优先查找局部)func()
  1. Enclosing(闭包外层)

适用于嵌套函数:在外层函数的作用域中查找

示例:

def outer():y = 20def inner():print(y)  # 查找闭包外层的 y → 20inner()outer()
  1. Global(全局作用域)

模块级变量:在函数外部定义的变量

示例:

z = 30
def func():print(z)  # 查找全局的 z → 30func()
  1. Built-in(内置作用域)

Python 内置函数/变量:如 len, str, True

示例:

def func():print(len)  # 找到内置函数 len → <built-in function len>func()

关键注意

  • 赋值操作的影响

若在函数内部对变量赋值,Python 会默认将其视为局部变量(即使全局存在同名变量)

x = 100
def func():x = 200    # 创建新的局部变量print(x)   # 输出 200func()
print(x)       # 输出 100(全局变量未变)
  • global 关键字 强制使用全局变量
x = 100
def func():global xx = 200    # 修改全局变量print(x)   # 输出 200func()
print(x)       # 输出 200
  • nonlocal 关键字 在嵌套函数中使用外层非全局变量
def outer():x = 10def inner():nonlocal xx = 20  # 修改闭包外层的 xinner()print(x)    # 输出 20outer()
  • 变量未定义时的报错,若所有作用域均未找到变量:
def func():print(undefined_var)  # 报错 NameErrorfunc()
函数内访问变量
是局部变量?
使用局部变量
是闭包外层变量?
使用外层变量
是全局变量?
使用全局变量
是内置变量?
使用内置变量
抛出 NameError

本文小结

本文有关Python中初级函数话题到这里就结束了,后面的文章我们会展开继续 Python函数的更多话题,如内置高级函数,lambda表达式,任意实参列表等等… 感谢您的观看!

如果你觉得这篇文章对你有所帮助,请为我的博客 点赞👍收藏⭐️ 评论💬或 分享🔗 支持一下!你的每一个支持都是我继续创作的动力✨!🙏
如果你有任何问题或想法,也欢迎 留言💬 交流,一起进步📚!❤️ 感谢你的阅读和支持🌟!🎉
祝各位大佬吃得饱🍖,睡得好🛌,日有所得📈,逐梦扬帆⛵!

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

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

相关文章

夜天之书 #106 Apache 软件基金会如何投票选举?

近期若干开源组织进行换届选举。在此期间&#xff0c;拥有投票权的成员往往会热烈讨论&#xff0c;提名新成员候选人和治理团队的候选人。虽然讨论是容易进行的&#xff0c;但是实际的投票流程和运作方式&#xff0c;在一个成员众多的组织中&#xff0c;可能会有不少成员并不清…

DeepSeek开源周 Day04:从DualPipe聊聊大模型分布式训练的并行策略

DualPipe简介 今天是DeepSeek开源周的第四天&#xff0c;官方开源了一种新型并行计算优化策略——DualPipe。 其实大家阅读过Deepseek-V3技术报告的同学&#xff0c;对这个技术并不陌生。 开源地址&#xff1a;https://github.com/deepseek-ai/DualPipe 核心亮点 DualPipe&…

React:B站评论demo,实现列表渲染、删除按钮显示和功能实现、导航栏渲染切换及高亮显示、评论区的排序

功能要求&#xff1a; 1、渲染评论列表 2、删除评论功能&#xff1a;只显示自己评论的删除按钮&#xff1b;点击删除按钮&#xff0c;删除当前评论&#xff0c;列表中不再显示。 3、渲染导航Tab&#xff08;最新 | 最热&#xff09;和其 高亮实现 4、评论排序功能实现&…

一文了解:部署 Deepseek 各版本的硬件要求

很多朋友在咨询关于 DeepSeek 模型部署所需硬件资源的需求&#xff0c;最近自己实践了一部分&#xff0c;部分信息是通过各渠道收集整理&#xff0c;so 仅供参考。 言归正转&#xff0c;大家都知道&#xff0c;DeepSeek 模型的性能在很大程度上取决于它运行的硬件。我们先看一下…

C#贪心算法

贪心算法&#xff1a;生活与代码中的 “最优选择大师” 在生活里&#xff0c;我们常常面临各种选择&#xff0c;都希望能做出最有利的决策。比如在超市大促销时&#xff0c;面对琳琅满目的商品&#xff0c;你总想用有限的预算买到价值最高的东西。贪心算法&#xff0c;就像是一…

【JAVA SE基础】抽象类和接口

目录 一、前言 二、抽象类 2.1 抽象类的概念 2.2 抽象类语法 2.3 抽象类特性 2.4 抽象类的作用 三、接口 3.1 什么是接口 3.2 语法规则 3.3 接口使用 3.4 接口特性 3.5 实现多接口 3.6 接口间的继承 四、Object类 4.1 获取对象信息&#xff08; toString() &…

查找Excel包含关键字的行(の几种简单快速方法)

需求&#xff1a;数据在后缀为xlsx的Excel的sheet1中且量比较大&#xff0c;比如几十万行几百列&#xff1b;想查找一个关键字所在的行,比如"全网首发"&#xff1b; 情况①知道关键字在哪一列 情况②不确定在哪一列&#xff0c;很多列相似又不同&#xff0c;本文演…

网络运维学习笔记(DeepSeek优化版)009网工初级(HCIA-Datacom与CCNA-EI)路由理论基础与静态路由

文章目录 路由理论基础核心概念路由表六要素路由选路原则加表规则选路优先级 协议与参数常见协议号路由协议优先级对比 网络架构基础AS&#xff08;autonomous system&#xff0c;自治系统&#xff09;路由分类 静态路由(static routing)实验拓扑思科配置示例华为配置示例 典型…

Python 绘制迷宫游戏,自带最优解路线

1、需要安装pygame 2、上下左右移动&#xff0c;空格实现物体所在位置到终点的路线&#xff0c;会有虚线绘制。 import pygame import random import math# 迷宫单元格类 class Cell:def __init__(self, x, y):self.x xself.y yself.walls {top: True, right: True, botto…

基于Springboot博物馆文博资源库系统【附源码】

基于Springboot博物馆文博资源库系统 效果如下&#xff1a; 系统登陆页面 文物信息管理页面 流动申请页面 文物报修页面 个人信息页面 文物保修管理页面 系统主页面 文物类型页面 研究背景 随着信息技术的飞速发展&#xff0c;博物馆文博资源的管理与利用日益受到重视。传统…

【考试大纲】初级信息系统运行管理员考试大纲

目录 引言一、考试要求1、 考试说明2、 考试要求3、 本考试设置的科目包括:二、考试范围考试科目1:信息系统基础知识(初级)考试科目2:信息系统运行管理(应用技术)引言 最新的信息系统运行管理员考试大纲出版于 2018 年 9 月,本考试大纲基于此版本整理。 一、考试要求…

基于单片机的智能扫地机器人

1 电路设计 1.1 电源电路 本电源采用两块LM7805作为稳压电源&#xff0c;一块为控制电路和传感器电路供电&#xff0c;另一块单独为电机供电。分开供电这样做的好处&#xff0c;有利于减小干扰&#xff0c;提高系统稳定性。 LM7805是常用的三端稳压器件&#xff0c;顾名思义0…

传输层协议TCP

TCP全称为 传输控制协议(Transmission Control Protocol)&#xff0c;就是要对数据的传输进行一个详细的控制。 TCP协议段格式 源端口&#xff1a;发送方的端口号&#xff0c;用来标识发送端的应用程序或进程。 目标端口&#xff1a;接收方的端口号&#xff0c;用来标识接收端…

ST-LINK端口连接失败,启动GDB server失败的问题处理方法,有效

目录 1. 问题描述2. 解决办法2.1 后台关闭2.2 后台关闭无法找到ST进程或者关闭后未解决 1. 问题描述 报错&#xff1a; Failed to bind to port 61235, error code -1: No error Failure starting SWV server on TCP port: 61235 Failed to bind to port 61234, error code -1…

如何评估所选择的PHP后端框架的性能?

大家在选择PHP后端框架的时候&#xff0c;如果想评估其性能如何&#xff0c;能不能扛得住你的项目&#xff1f;可以根据以下几点进行分析&#xff0c;帮助大家选择到更符合自己心目中的PHP后端框架。 1. 基准测试 基准测试是评估框架性能的基础方法&#xff0c;主要通过模拟高…

P8649 [蓝桥杯 2017 省 B] k 倍区间--前缀和--同余定理【蓝桥杯简单题-必开long long】

P8649 [蓝桥杯 2017 省 B] k 倍区间--前缀和--同余定理 题目 分析代码 还有一件事【老爹音】 题目 分析 首先&#xff0c;看到”连续子序列求和”这一要求时&#xff0c;我们果断选择前缀和解答。 接着就要用到一个非常巧妙的“同余定理”——如果 sum[j] % K sum[i] % K&am…

如何免费使用稳定的deepseek

0、背景&#xff1a; 在AI辅助工作中&#xff0c;除了使用cursor做编程外&#xff0c;使用deepseek R1进行问题分析、数据分析、代码分析效果非常好。现在我经常会去拿行业信息、遇到的问题等去咨询R1&#xff0c;也给了自己不少启示。但是由于官网稳定性很差&#xff0c;很多…

【愚公系列】《Python网络爬虫从入门到精通》036-DataFrame日期数据处理

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…

PDF文档中表格以及形状解析

我们在做PDF文档解析时有时需要解析PDF文档中的表格、形状等数据。跟解析文本类似的常见的解决方案也是两种。文档解析跟ocr技术处理。下面我们来看看使用文档解析的方案来做PDF文档中的表格、图形解析&#xff08;使用pdfium库&#xff09;。 表格解析&#xff1a; 在pdfium库…

ES、OAS、ERP、电子政务、企业信息化(高软35)

系列文章目录 ES、OAS、ERP、电子政务、企业信息化 文章目录 系列文章目录前言一、专家系统&#xff08;ES&#xff09;二、办公自动化系统&#xff08;OAS&#xff09;三、企业资源规划&#xff08;ERP&#xff09;四、典型信息系统架构模型1.政府信息化和电子政务2.企业信息…