257 lines
6.2 KiB
Markdown
257 lines
6.2 KiB
Markdown
|
|
# Python 范围
|
|||
|
|
|
|||
|
|
> 原文:<https://www.pythonforbeginners.com/basics/python-scope>
|
|||
|
|
|
|||
|
|
在用 python 编程时,我们必须处理各种各样的结构,比如变量、函数、模块、库等等。在一些情况下,在一个地方使用的变量名也可能在不同的地方使用,而与前面的定义没有任何关系。在这篇关于 python 作用域的文章中,我们将尝试理解 python 解释器如何处理变量的定义。
|
|||
|
|
|
|||
|
|
## Python 中的作用域是什么?
|
|||
|
|
|
|||
|
|
当我们在程序中定义一个变量、函数或类名时,它只能在程序的某个区域中被访问。在这个区域中,名字一旦被定义,就可以用来标识一个对象、一个变量或一个函数,这个区域称为作用域。根据变量或函数名的定义,范围可以从单个代码块(如函数)扩展到整个运行时环境。
|
|||
|
|
|
|||
|
|
范围的概念与名称空间密切相关,范围是作为名称空间实现的。我们可以把名称空间看作是一个将对象名称映射到对象的 [python 字典](https://www.pythonforbeginners.com/dictionary/how-to-use-dictionaries-in-python/)。字典的键对应于名称,值对应于 python 中的对象。
|
|||
|
|
|
|||
|
|
在 python 中,有四种类型的作用域定义,即内置作用域、全局作用域、局部作用域和封闭作用域。我们将在接下来的章节中研究所有这些。
|
|||
|
|
|
|||
|
|
## Python 中的内置作用域是什么?
|
|||
|
|
|
|||
|
|
python 中的内置作用域包含内置对象和函数定义。它是使用 python 最新版本中的内置模块实现的。
|
|||
|
|
|
|||
|
|
每当我们启动 python 解释器时,内置模块就会自动加载到我们的运行时环境中。因此,我们可以在程序中访问模块中定义的所有函数和对象,而无需导入它们。
|
|||
|
|
|
|||
|
|
像 print()、abs()、input()、int()、float()、string()、sum()、max()、sorted()等类似的函数,在使用前不需要导入,都是在内置作用域中定义的。我们可以看看内置作用域中可用的函数和对象定义,如下所示。
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
builtin_names = dir(__builtins__)
|
|||
|
|
for name in builtin_names:
|
|||
|
|
print(name)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
输出:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
ArithmeticError
|
|||
|
|
AssertionError
|
|||
|
|
AttributeError
|
|||
|
|
BaseException
|
|||
|
|
BlockingIOError
|
|||
|
|
BrokenPipeError
|
|||
|
|
BufferError
|
|||
|
|
BytesWarning
|
|||
|
|
ChildProcessError
|
|||
|
|
ConnectionAbortedError
|
|||
|
|
ConnectionError
|
|||
|
|
ConnectionRefusedError
|
|||
|
|
ConnectionResetError
|
|||
|
|
DeprecationWarning
|
|||
|
|
EOFError
|
|||
|
|
Ellipsis
|
|||
|
|
EnvironmentError
|
|||
|
|
Exception
|
|||
|
|
False
|
|||
|
|
FileExistsError
|
|||
|
|
FileNotFoundError
|
|||
|
|
FloatingPointError
|
|||
|
|
FutureWarning
|
|||
|
|
GeneratorExit
|
|||
|
|
IOError
|
|||
|
|
ImportError
|
|||
|
|
ImportWarning
|
|||
|
|
IndentationError
|
|||
|
|
IndexError
|
|||
|
|
InterruptedError
|
|||
|
|
IsADirectoryError
|
|||
|
|
KeyError
|
|||
|
|
KeyboardInterrupt
|
|||
|
|
LookupError
|
|||
|
|
MemoryError
|
|||
|
|
ModuleNotFoundError
|
|||
|
|
NameError
|
|||
|
|
None
|
|||
|
|
NotADirectoryError
|
|||
|
|
NotImplemented
|
|||
|
|
NotImplementedError
|
|||
|
|
OSError
|
|||
|
|
OverflowError
|
|||
|
|
PendingDeprecationWarning
|
|||
|
|
PermissionError
|
|||
|
|
ProcessLookupError
|
|||
|
|
RecursionError
|
|||
|
|
ReferenceError
|
|||
|
|
ResourceWarning
|
|||
|
|
RuntimeError
|
|||
|
|
RuntimeWarning
|
|||
|
|
StopAsyncIteration
|
|||
|
|
StopIteration
|
|||
|
|
SyntaxError
|
|||
|
|
SyntaxWarning
|
|||
|
|
SystemError
|
|||
|
|
SystemExit
|
|||
|
|
TabError
|
|||
|
|
TimeoutError
|
|||
|
|
True
|
|||
|
|
TypeError
|
|||
|
|
UnboundLocalError
|
|||
|
|
UnicodeDecodeError
|
|||
|
|
UnicodeEncodeError
|
|||
|
|
UnicodeError
|
|||
|
|
UnicodeTranslateError
|
|||
|
|
UnicodeWarning
|
|||
|
|
UserWarning
|
|||
|
|
ValueError
|
|||
|
|
Warning
|
|||
|
|
ZeroDivisionError
|
|||
|
|
__build_class__
|
|||
|
|
__debug__
|
|||
|
|
__doc__
|
|||
|
|
__import__
|
|||
|
|
__loader__
|
|||
|
|
__name__
|
|||
|
|
__package__
|
|||
|
|
__spec__
|
|||
|
|
abs
|
|||
|
|
all
|
|||
|
|
any
|
|||
|
|
ascii
|
|||
|
|
bin
|
|||
|
|
bool
|
|||
|
|
breakpoint
|
|||
|
|
bytearray
|
|||
|
|
bytes
|
|||
|
|
callable
|
|||
|
|
chr
|
|||
|
|
classmethod
|
|||
|
|
compile
|
|||
|
|
complex
|
|||
|
|
copyright
|
|||
|
|
credits
|
|||
|
|
delattr
|
|||
|
|
dict
|
|||
|
|
dir
|
|||
|
|
divmod
|
|||
|
|
enumerate
|
|||
|
|
eval
|
|||
|
|
exec
|
|||
|
|
exit
|
|||
|
|
filter
|
|||
|
|
float
|
|||
|
|
format
|
|||
|
|
frozenset
|
|||
|
|
getattr
|
|||
|
|
globals
|
|||
|
|
hasattr
|
|||
|
|
hash
|
|||
|
|
help
|
|||
|
|
hex
|
|||
|
|
id
|
|||
|
|
input
|
|||
|
|
int
|
|||
|
|
isinstance
|
|||
|
|
issubclass
|
|||
|
|
iter
|
|||
|
|
len
|
|||
|
|
license
|
|||
|
|
list
|
|||
|
|
locals
|
|||
|
|
map
|
|||
|
|
max
|
|||
|
|
memoryview
|
|||
|
|
min
|
|||
|
|
next
|
|||
|
|
object
|
|||
|
|
oct
|
|||
|
|
open
|
|||
|
|
ord
|
|||
|
|
pow
|
|||
|
|
print
|
|||
|
|
property
|
|||
|
|
quit
|
|||
|
|
range
|
|||
|
|
repr
|
|||
|
|
reversed
|
|||
|
|
round
|
|||
|
|
set
|
|||
|
|
setattr
|
|||
|
|
slice
|
|||
|
|
sorted
|
|||
|
|
staticmethod
|
|||
|
|
str
|
|||
|
|
sum
|
|||
|
|
super
|
|||
|
|
tuple
|
|||
|
|
type
|
|||
|
|
vars
|
|||
|
|
zip
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
内置作用域是在解释器加载后创建的,随着 python 解释器的关闭而被销毁。builtins 模块中定义的所有名称都在程序的内置范围内。
|
|||
|
|
|
|||
|
|
## 什么是全局范围?
|
|||
|
|
|
|||
|
|
我们用来编写代码的 python 脚本被 python 解释器称为 __main__ 模块。与 __main__ 模块相关联的作用域称为全局作用域。
|
|||
|
|
|
|||
|
|
对于任何 python 程序,只能有一个全局范围。一旦程序启动,全局范围就被创建,并随着 python 程序的终止而被销毁。
|
|||
|
|
|
|||
|
|
我们可以从下面的程序中理解全局范围的概念。
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
myNum1 = 10
|
|||
|
|
myNum2 = 10
|
|||
|
|
|
|||
|
|
def add(num1, num2):
|
|||
|
|
temp = num1 + num2
|
|||
|
|
|
|||
|
|
def print_sum():
|
|||
|
|
print(temp)
|
|||
|
|
|
|||
|
|
return temp
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
在上面的程序中,myNum1 和 myNum2 在程序的全局范围内。存在于全局范围内的对象是在任何代码块之外定义的。
|
|||
|
|
|
|||
|
|
## 什么是局部范围?
|
|||
|
|
|
|||
|
|
python 程序中的局部作用域是为函数等代码块定义的。python 程序中的每个函数都有自己的局部作用域,在这个作用域中定义了所有的变量和对象名。
|
|||
|
|
|
|||
|
|
当函数被任何其他函数调用时,函数的局部范围被加载。一旦函数终止,与之相关的局部作用域也会终止。
|
|||
|
|
|
|||
|
|
为了理解局部范围的概念,请看下面的例子。
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
myNum1 = 10
|
|||
|
|
myNum2 = 10
|
|||
|
|
|
|||
|
|
def add(num1, num2):
|
|||
|
|
temp = num1 + num2
|
|||
|
|
|
|||
|
|
def print_sum():
|
|||
|
|
print(temp)
|
|||
|
|
|
|||
|
|
return temp
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
在上面的程序中,变量 num1、num2 和 temp 存在于 add()函数的局部作用域中。这些名称只在执行 add()函数之前存在。
|
|||
|
|
|
|||
|
|
## Python 中的封闭作用域是什么?
|
|||
|
|
|
|||
|
|
每当一个函数被定义在任何其他函数内部时,内部函数的作用域就被定义在外部函数的作用域内部。因此,外部函数的范围被称为内部函数的封闭范围。
|
|||
|
|
|
|||
|
|
我们可以访问一个函数中所有的变量名,这个函数已经在它的封闭作用域中定义了。但是,我们不能访问在内部函数中定义的外部函数中的变量名。从下面的例子可以更清楚地看出这一点。
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
myNum1 = 10
|
|||
|
|
myNum2 = 10
|
|||
|
|
|
|||
|
|
def add(num1, num2):
|
|||
|
|
temp = num1 + num2
|
|||
|
|
|
|||
|
|
def print_sum():
|
|||
|
|
print(temp)
|
|||
|
|
|
|||
|
|
return temp
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这里,print_sum()函数存在于 add()函数的局部作用域中。因此,在 add()函数中定义的变量名 num1、num2 和 temp 可在 print_sum()函数的作用域中访问。
|
|||
|
|
|
|||
|
|
## 结论
|
|||
|
|
|
|||
|
|
在本文中,我们研究了 python 中的范围概念。我们还研究了不同的作用域类型及其示例。要阅读其他 python 概念,如[列表理解](https://www.pythonforbeginners.com/basics/list-comprehensions-in-python),敬请关注。
|