Python基础:作用域和命名空间

命名空间是存储变量的地方,而作用域则是变量的有效范围。

  • 作用域(Scope)指的是变量的有效范围。Python中的作用域分为三种:
    • 局部作用域指的是函数内部的范围;
    • 全局作用域指的是程序中所有函数之外的范围;
    • 内置作用域指的是Python解释器内置的范围。
  • 命名空间(Namespace)指的是变量存储的位置。Python中的变量存储在不同的命名空间中:
    • Local Scope:局部命名空间,包含了函数内部定义的变量和函数名字;
    • Enclosing Scope:外部嵌套函数的命名空间,包含了嵌套函数中定义的变量和函数名字;
    • Global Scope:全局命名空间,包含了模块中定义的变量和函数名字;
    • Built-in Scope:内置命名空间,包含了Python解释器内置的函数和变量名字。

简单来说,在一个函数func()中,它的局部命名空间即为func,内部定义的属性或方法都在这个命名空间中,其生效的范围(作用与域)为该函数内部。

为了辅助后面的讲解,下面先介绍几个python的内置函数

  • locals() 用于查看当前作用域的命名空间中的变量。它返回的是一个字典,字典的键是变量名,字典的值是变量的值。只能在函数内部使用。
  • globals() 用于查看全局作用域的命名空间中的变量。它返回的是一个字典,字典的键是变量名,字典的值是变量的值。可以在任何地方使用。
  • dir(object) 如果没有实参,则返回当前本地作用域中的名称列表。如果有实参,它会尝试返回该对象的有效属性列表。如果对象有一个名为 __dir__() 的方法,那么该方法将被调用,并且必须返回一个属性列表。

下面简单说明一下用法

a = 1
print('globals:', globals())
print('dir:', dir())

 输出为:

globals: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0000013C08576CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\project\\python100days\\1.py', '__cached__': None, 'a': 1}
dir: ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a']

可以看到dir()返回的列表是所有属性的变量名,而globals()返回的是字典,包括了前面的变量名和每个变量的值

接下来我们再来看命名空间和作用域的例子 :

a = 1
def foo():
    b = 2
    print("foo内部的局部命名空间:", locals())
    print("foo内部的全局命名空间:", globals())
    print('foo内部的当前命名空间(应为当前局部命名空间):', dir())

foo()
print('foo外部的全局命名空间:', globals())
print('foo外部的当前命名空间(应为全局命名空间):', dir())
print('全局命名空间中’foo‘的命名空间:', dir(foo))

输出:

foo内部的局部命名空间: {'b': 2}
foo内部的全局命名空间: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002C6C3346CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\project\\python100days\\1.py', '__cached__': None, 'a': 1, 'foo': <function foo at 0x000002C6C338F160>}
foo内部的当前命名空间(应为当前局部命名空间): ['b']
foo外部的全局命名空间: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000002C6C3346CD0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:\\project\\python100days\\1.py', '__cached__': None, 'a': 1, 'foo': <function foo at 0x000002C6C338F160>}
foo外部的当前命名空间(应为全局命名空间): ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'foo']
全局命名空间中’foo‘的命名空间: ['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

这里可以看出:
1、全局命名空间再foo内部和外部都是一样的;
2、在foo内部时,dir输出当前命名空间即为局部命名空间;在foo外部时,dir输出当前命名空间为全局命名空间。
3、dir(foo)时,输出函数对象的属性和方法的名称列表,包括函数的内置属性和方法,以及函数对象可用的特殊方法。(ps:对于一个函数对象,其中一些属性和方法是 Python 解释器自动添加的,例如 __call__ 方法,它定义了函数对象的调用方式)

猜你喜欢

转载自blog.csdn.net/qq_36497369/article/details/130128616