python基础 — 变量和作用域

1、命名空间

namespace (命名空间)是一个从名字到对象的映射,大部分命名空间当前都由 Python 字典实现。

(1)Python 中命名空间分类:

  • 内置命名空间(Built-in Namespace):包含 Python 解释器自带的函数和变量名,可以使用 dir(__builtins__) 查看并使用这些函数和变量。
  • 全局命名空间(Global Namespace):定义在脚本或模块层级的命名空间,可以在全局范围内使用。全局命名空间可以通过 globals() 查看。
  • 局部命名空间(Local Namespace):定义在函数或类中的命名空间,在函数或类内部可以使用。每次函数调用都会创建一个新的局部命名空间,函数调用结束后局部命名空间会被销毁。

(2)Python中命名空间的生命周期:

  • 内置命名空间:Python解释器启动时自动创建,直到解释器关闭才会销毁。
  • 全局命名空间:模块被导入时创建,模块被解释器清除时销毁。
  • 局部命名空间:调用该函数时创建,并在函数返回或抛出不在函数内部处理的错误时被删除。 (实际上,用“遗忘”来描述实际发生的情况会更好一些。) 当然,每次递归调用都会有自己的本地命名空间。

2、作用域

作用域(scope)是一个命名空间可直接访问的 Python 程序的文本区域。说人话就是,Python作用域指的是变量的生命周期以及其可被访问的范围。

(1)Python 作用域分类:

  • 内置作用域(built-in):Python解释器内置的函数和变量,在任何地方都可以使用。
  • 全局作用域(global):定义在函数外部的变量拥有全局作用域,意味着它们可以在模块的任何地方被访问。
  • 局部作用域(local):定义在函数内部的变量拥有局部作用域,意味着它们只能在函数内被访问。
  • 嵌套作用域(enclosed):在嵌套函数中,内层函数可以访问外层函数的变量,但是不包括全局作用域中的变量。

(2)Python作用域的生命周期:

  • 内置作用域是永久的,会在解释器启动时自动加载;
  • 全局作用域在程序开始时创建,并在程序结束时销毁;
  • 局部作用域在函数被调用时创建,并在函数执行完毕后销毁;
  • 非局部作用域是一个函数内嵌套函数时的作用域,变量可在内层函数和外层函数间共享,当外层函数执行完毕后,非局部作用域也会被销毁。

(3)Python中命名空间和作用域的区别:

  • Python中,命名空间是一个包含标识符和它们的值之间的关系的映射表,是一个字典。而作用域表示一个标识符可见或可访问的区域。

 3、变量

在Python中,变量是用于存储数据的标识符。它们用于给数据赋予一个名称,并且可以在程序中随时引用和修改这些数据。

当我们创建一个变量时,实际上是在内存中分配了一块空间来存储数据,并且将变量名与这块内存空间关联起来。这样,我们可以通过变量名来访问和操作存储在内存中的数据。

(1)创建变量:

变量的创建非常简单,只需要使用等号(=)将变量名和对应的值进行赋值操作。

例如:

x = 5            # 将数字 5 赋值给变量 x

name = "Alice"   # 将字符串 "Alice" 赋值给变量 name

is_sunny = True  # 将布尔值 True 赋值给变量 is_sunny

注意,可以使用逗号分隔多个变量,并将它们分别赋予相应的值:

x, y, z = 1, 2, 3  # 将整数 1、2、3 分别赋值给变量 x、y、z

name, age = "Bob", 25  # 将字符串 "Bob" 和整数 25 分别赋值给变量 name、age

(2)变量命名规则:

  • 变量名只能包含字母、数字和下划线(_),不能以数字开头。
  • 变量名区分大小写,例如 a 和 A 是两个不同的变量。
  • 避免使用Python 的关键字(如 if、else、while 等)作为变量名。
  • 变量名应具有描述性,以提高代码可读性。

(3)调用变量:

使用变量时只需要调用其名称即可。例如,以下代码会打印出变量 x 的值:

print(x)

(4)删除变量:

使用del语句可以删除一个变量及其对应的值,例如:

x = 5
del x # 删除变量 x

4、全局变量和局部变量

Python 中根据作用域的不同可以把变量分为全局变量和局部变量,变量的作用域在定义时就被固定了。

详见:Global and Local Variables in Python - GeeksforGeeks

(1)变量的分类:

  • 全局变量(global variable):定义在函数或类外部,作用域为整个模块,可被模块内的所有函数和方法访问。
  • 局部变量(local variable):定义在函数或类内部,作用域只限于当前函数或方法内部,外部无法访问。
  • 非局部变量(nonlocal variable):局部变量的一种,定义在嵌套函数中,且被内函数引用的变量,需要使用nonlocal关键字。

(2)变量的生命周期:

  • 当变量被创建时,它进入当前所处作用域;
  •  在作用域内,变量可以被使用,更新或删除;
  • 变量在离开作用域时被销毁。 

(3)变量的查找顺序(LEGB):

  • 遵循LEGB原则,Python解释器会从当前作用域开始查找这个变量,按照局部作用域>>嵌套作用域>>全局作用域>>内置作用域的顺序查找。如果查找到最外层的内置作用域也找不到,Python将引发一个NameError异常。

 例子如下:

x = 10  # global variable

def func():
    y = 5  # local variable
    print(x, y)

func()  # 输出:10 5
print(y)  # 报错,因为 y 是一个局部变量,不在全局范围内

5、访问外部变量

正常情况下,在函数内是可以直接访问外部变量的(注意,这里的外部变量指的是全局变量和外层的局部变量,这些变量将是只读的,不可以修改它们。这个时候只会在内部函数的作用域中创建一个新的局部变量,而同名的外部变量保持不变)。如果想要进行赋值和修改这些外部变量,我们需要用到关键字 `global` 或 `nonlocal` 。

(1)直接访问外部变量

a = 10  # global variable

# Accessing global Variable From Inside a Function
def test_scope():
    b = a + 10
    print(b)

# calling a function
test_scope()

输出:20

说明: 在函数test_scope中直接访问了外部变量a(全局变量),表达式"b = a+10",左侧的b是局部变量,右侧的a是外部变量a。

(2)不可以直接修改外部变量

a = 10  # global variable

# Modifying Global Variable From Inside the Function
def test_scope():
    a = a + 10
    print(a)

# calling a function
test_scope()

输出报错信息:

UnboundLocalError: local variable 'a' referenced before assignment

说明: 在函数test_scope中,表达式"a = a+10",左侧的a是全局变量,右侧的a是局部变量,在给左侧的全局变量a赋值的时候没有初始化右侧局部变量a的值,所以报错了。

6、global关键字

使用 global关键字来访问全局变量。详见:Global keyword in Python - GeeksforGeeks

a = 10  # global variable

# Modifying Global Variable From Inside the Function
def test_scope():
    global a
    a = a + 10
    print(a)

# calling a function
test_scope()

输出:20

说明: 在函数test_scope中,添加一行代码 global a实现在函数内部将变量a声明为全局变量a,初始值为10。

7、nonlocal关键字

使用 nonlocal关键字访问局部变量。详见:Python nonlocal Keyword - GeeksforGeeks

def outer():
    a = 100  # Our local variable

    def inner():
        nonlocal a  # Reference a in the upper scope
        a = 200  # Overwrite this variable
        print(a)

    inner() # Calling inner function

    print(a) # Printing local variable

# Calling outer function
outer()

输出:

200
200

说明:内函数inner中,nonlocal a将这里的局部变量标记为上层作用域outer函数中的局部变量a = 100,并将值修改为200。


reference:

Python作用域和命名空间 — Python 3.8.16 文档

Global and Local Variables in Python - GeeksforGeeks

Global keyword in Python - GeeksforGeeks

Python nonlocal Keyword - GeeksforGeeks

PEP 3104 – Access to Names in Outer Scopes

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值