【 一 】名称空间
【 1 】什么是名称空间
Python中的名称空间是基于字典(Dictionary)实现的,其中每个键都是变量名或函数名,对应的值是变量或函数的引用。当程序访问一个变量或函数时,Python会首先在当前名称空间进行查找,如果找到则直接返回;否则会继续向上一级名称空间查找,直到查找到全局名称空间或内置名称空间。如果仍然找不到,则会抛出NameError
异常。
【 2 】内置名称空间
内置名称空间(Built-in Namespace):这个名称空间存储了Python解释器自带的函数和变量,无需导入即可使用,例如print()
和len()
函数等。
- 内置函数:Python内置了一些常用的函数,例如
print()
、len()
、type()
等。你可以直接在任何地方调用这些函数,无需导入模块。
print("Hello, world!") # 使用内置的print函数
length = len([1, 2, 3, 4, 5]) # 使用内置的len函数
data_type = type(10) # 使用内置的type函数
2.内置异常:Python内置了一些异常类型,例如ValueError
、TypeError
等。当发生相应的错误时,会引发这些异常。
try:
result = 10 / '2' # 会引发内置的TypeError异常
except TypeError as e:
print("发生了TypeError异常:", e)
3. 内置对象:Python中还有一些内置的对象,例如True
、False
、None
等。
if True: # 使用内置的True对象
print("条件成立")
else:
print("条件不成立")
if None: # 使用内置的None对象
print("这条语句不会被执行")
这些都是内置名称空间中的对象和函数,你可以在任何地方直接使用它们,而无需进行额外的导入操作。这正体现了内置名称空间的便利之处。
【 3 】全局名称空间
全局名称空间(Global Namespace)是指在Python程序中定义的全局变量和函数所在的名称空间。它包含了在程序的顶层定义的、没有嵌套在函数或类定义中的变量和函数。
全局名称空间可以在程序的任何地方访问,而不仅限于函数内部或类内部。在Python程序执行时,全局名称空间会在程序启动时创建,并在整个程序执行期间一直存在。当程序需要访问一个变量或函数时,Python会首先在当前名称空间进行查找,如果找不到则会继续向上一级名称空间查找,直到在全局名称空间中找到相应的对象。
下面是一个简单的例子,演示了如何在全局名称空间中定义变量和函数:
# 在全局名称空间中定义变量和函数
name = "Alice" # 定义一个名为name的字符串变量
def greet():
print("Hello, world!") # 定义一个名为greet的函数
# 在程序中的任何地方访问全局名称空间中的变量和函数
print("My name is", name) # 访问全局名称空间中的name变量
greet() # 调用全局名称空间中的greet函数
在这个例子中,我们在程序的顶层定义了一个名为name
的字符串变量和一个名为greet()
的函数,并在程序的其他地方访问了它们。这些变量和函数都是定义在全局名称空间中的,因此可以在程序的任何地方访问。
需要注意的是,虽然全局名称空间可以在程序的任何地方访问,但在不同的函数或类定义中定义的变量和函数是不同的。因此,在编写程序时需要考虑变量和函数的作用域和生命周期,避免出现意外的错误。
【 4 】局部名称空间
局部名称空间(Local Namespace)是指在函数或类的定义中创建的名称空间,用于存储函数内部或类内部定义的变量、函数和其他对象。
当程序执行到一个函·或类的定义时,会在内存中创建一个新的局部名称空间,并将该名称空间与函数或类相关联。在这个局部名称空间中,可以定义和使用该函数或类内部的变量、函数和其他对象。
下面是一个简单的例子,演示了如何在函数和类中创建和使用局部名称空间:
def greet():
name = "Alice" # 在函数内部定义一个局部变量
print("Hello,", name) # 在函数内部访问局部变量
greet() # 调用函数
class MyClass:
def __init__(self):
self.value = 42 # 在类中定义一个实例变量
def print_value(self):
print("The value is", self.value) # 在类的方法中访问实例变量
obj = MyClass() # 创建类的实例
obj.print_value() # 调用类的方法
# Hello, Alice
# The value is 42
【5】名称空间的加载顺序
- 内置名称空间->全局名称空间->局部名称空间,
- 而查找一个名字,必须从三个名称空间之一找到,查找顺序为:
- 局部名称空间->全局名称空间->内置名称空间。
【 二 】作用域
作用域(Scope)是指在程序中定义变量的区域,它决定了变量的可见性和生命周期。
【 1 】全局作业域
全局作用域是程序中最外层的作用域,即全局名称空间。在全局作用域中定义的变量和函数可以在整个程序的任何地方被访问。
当你在程序的最外层定义一个变量或函数时,它们会成为全局变量或全局函数。这意味着它们可以在程序的任何位置进行访问,包括在函数内部。
示例:
x = 10 # 全局变量
def foo():
print("在函数内部访问全局变量x:", x)
foo()
print("在全局作用域中访问全局变量x:", x)
输出结果为:
在函数内部访问全局变量x: 10
在全局作用域中访问全局变量x: 10
在这个示例中,x
是在全局作用域中定义的全局变量。它可以在程序的任何位置被访问,包括在函数内部。在foo()
函数内部,我们可以直接使用变量x
来访问全局作用域中的变量。
需要注意的是,在函数内部如果要修改全局变量的值,需要使用
global
关键字来声明该变量是全局变量,否则会被当作局部变量处理。
【 2 】局部作用域
局部作用域是指在函数内部定义的作用域,也称为局部名称空间。在局部作用域中定义的变量和函数只能在其所在函数内部被访问。
当你在一个函数内部定义一个变量或函数时,它们将成为该函数的局部变量或局部函数。这意味着它们只能在该函数内部被访问,而在函数外部是不可见的。
示例:
def foo():
y = 5 # 局部变量
print("在函数内部访问局部变量y:", y)
foo()
print("在全局作用域中尝试访问局部变量y:", y)
输出结果为:
在函数内部访问局部变量y: 5
Traceback (most recent call last):
File "C:\Users\小白\PycharmProjects\pythonProject1\12\1.py", line 132, in <module>
print("在全局作用域中尝试访问局部变量y:", y)
NameError: name 'y' is not defined
【 3 】嵌套作用域
嵌套作用域是指在函数内部定义的内部作用域,它可以访问外部作用域中的变量。具体而言,当一个函数内部定义了另一个函数时,内部函数可以访问外部函数中的变量和函数。
示例:
def outer_func():
x = 10 # 外部函数的局部变量
def inner_func():
y = 5 # 内部函数的局部变量
result = x + y # 访问外部函数的变量
print("内部函数中的结果:", result)
inner_func()
print("外部函数中的变量x:", x)
outer_func()
输出结果为:
内部函数中的结果: 15
外部函数中的变量x: 10
在这个示例中,我们定义了一个外部函数outer_func()
和一个内部函数inner_func()
。在内部函数中,我们可以访问外部函数中的变量x
。在内部函数中,我们将外部函数的变量x
与内部函数的变量y
相加,并打印出结果。
需要注意的是,内部函数可以访问外部函数的变量,但不能直接修改外部函数的变量。如果需要在内部函数中修改外部函数的变量,可以使用
nonlocal
关键字声明该变量为非局部变量。
【 4 】内置作用域
内置作用域(Built-in scope)是指 Python 的内置命名空间,其中包含了 Python 内部定义的函数和变量。这些函数和变量都可以直接在 Python 代码中使用,而不需要进行导入或定义。
例如,Python 中常用的 print()
函数、len()
函数、range()
函数等都是内置函数,它们可以在任何地方直接调用,而不需要导入其他模块。
同样,内置作用域还包含了一些内置变量,如 True
、False
、None
、int
、float
、str
、list
、tuple
、dict
等等,这些变量也可以在任何地方直接使用。
我们可以通过dir(__builtins__)来查看所用的内置函数和变量。
import builtins
# 打印所有内置变量和函数
print(dir(builtins))
# 调用内置函数
print(len([1, 2, 3, 4]))
print(range(10))
# 使用内置变量
print(True)
print(int("123"))
输出结果:
['__build_class__', '__import__', ..., 'len', 'list', 'map', 'max', ..., 'True', 'tuple', 'type', ...]
4
range(0, 10)
True
123
需要注意的是,虽然内置作用域中的函数和变量可以直接使用,但是它们的作用域仅限于全局作用域,不能在函数内部使用。如果你想在函数内部使用内置函数和变量,需要将它们作为参数传递给函数或者在函数内部重新定义。
【 三 】作用域总结:
作用域决定了在程序中如何访问和使用变量。当需要访问一个变量时,Python会按照以下顺序依次查找变量:
- 当前作用域:首先在当前作用域中查找变量,即局部作用域或嵌套作用域。
- 上一级作用域:如果在当前作用域中找不到变量,则继续向上一级作用域查找,直到在全局作用域中找到变量。
- 全局作用域:如果在全局作用域中也找不到变量,则会引发
NameError
异常。
需要注意的是,在函数内部可以访问外部作用域的变量,但不能直接修改它们。如果要在函数内部修改外部作用域的变量,可以使用global
关键字声明变量为全局变量。
以下是一个简单的示例,展示了不同作用域中变量的可见性和访问规则:
x = 10 # 全局作用域
def outer():
y = 20 # 外部函数作用域
def inner():
z = 30 # 内部函数作用域
print(x) # 访问全局作用域中的变量
print(y) # 访问外部函数作用域中的变量
print(z) # 访问当前作用域中的变量
inner()
outer()
总结起来,Python中的作用域规则遵循"就近原则",即先在当前作用域查找变量,再逐级向上查找,直到找到或抵达全局作用域。了解作用域概念对于理解变量的可见性和生命周期非常重要。