名字空间(namespace)

1)、名字(name)与对象(object)

对象:对象一块存储区域,用来存储值,同时包含对该值所支持的一系列方法,也包含一系列属性。

名字:每个名字对应一个对象,多个名字可以对应一个对象。这有点类似于别的语言中的别名。

2)、名字空间

名字空间:名字空间是用来专门存储名字与对象的对应关系的地方,在python中名字空间一般使用dict数据结构实现。

在python中,函数、模块等都有自己的命名空间:

局部命名空间(local namespace):即函数中定义的名称 —— 包括函数中的变量、参数、局部变量等;随函数而生,随函数而亡。

全局命名空间(global namespace):即模块中定义的名称 —— 包括模块中的变量、函数、类、参数、常量、导入(import)的模块等;随模块而生,随模块而亡。

内置命名空间(built-in namespace):即python内置的名称 —— 包括各种内置函数、Exception等;随解释器而生,随解释器而亡。

ps:实际上,class也会形成一个特殊的namespace。

而,当python需要使用变量时,会在上述命名空间中依次查找,顺序是:

局部命名空间,全局命名空间、内置命名空间。

同一命名空间中不能有重名,但不同命名空间可以。

  • 可以通过locals()(获取局部namespace)、globals()(获取全局namespace) 函数来获取命名空间的值(字典),在程序的不同位置执行结果不一定一致,因为结果是针对当前位置来说的。

ps:因为python是一行一行执行的,当有新的名字与object进行bind的时候,就会将该名字与object的对应关系加入到相应的namespace。

作用域(scope)

作用域:可以理解为变量所起作用的范围,超出范围则某变量不能被使用。在python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则报错。Python 中只有模块(module),类(class)以及函数(def、lambda)才会产生新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会产生新的作用域的。

ps: python使用静态作用域(词法作用域),即标识符的作用域只与它声明的位置有关,一旦声明,则作用域确认。标识符在使用前必须声明,注意函数在被调用前必须声明。

作用域可以分为四种:

Local:最内层,包含局部变量,一般指的是函数内部的作用域;

Enclosing:包含非局部但是也不是全局的变量,主要是嵌套时,外层函数的变量,那么相对内层函数来说,嵌套的外层函数中的变量既不是局部变量也不是全局变量。

Global:全局变量,例如当前模块中的全局变量。

Build-in:内置变量。

查找顺序一般是:Local--->Enclosing--->Global--->Build-in

当查找到一个对应的变量后,就停止继续外层作用域查找。

那么查找的位置就是对应的作用域中的namespace(随着代码的执行,namespace不断改变,添加名字或者删除名字。)。

作用域图:

  • 通过nonlocal可以将一个变量声明为外层作用域变量,即在一个内层作用域将一个name与外层作用域相关联,然后解释器就知道去外层作用域寻找该name对应的那个object了。
  • 通过global可以将一个变量声明为全局作用域变量,即在任何地方将一个name与全局作用域相关联,然后解释器就知道去全局作用域寻找该name对应的那个object了。

#一个典型的例子:

def scope_test():def do_local():spam = "local spam"    #local scopedef do_nonlocal():nonlocal spamspam = "nonlocal spam"  #outer scope,此时改变的scope_test中定义的spam的值。def do_global():global spamspam = "global spam"   #global scope,此时改变的是global scope中定义的spam的值。spam = "test spam"do_local()  #改变的是local scope中的spam。print("After local assignment:", spam)  #scope_test中的spam。do_nonlocal() #改变的是scope_test中的spam。print("After nonlocal assignment:", spam) #scope_test中的spam。do_global()  #改变的是global scope中的spam。 print("After global assignment:", spam)  #scope_test中的spam。scope_test()
print("In global scope:", spam)  #输出global scope中的spam。

运行结果:

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

#变量寻找的例子:

x=3
def g():print(x)  # local scope没有声明x,所以引用到global scope的x.

运行结果:3

x=3
def g():x=2   # 定义并赋值本地变量xprint(x)  # 引用本地变量x

运行结果:2

x=1
def g():print(x)x=2
g()

运行结果:出错。

python解释器运行python代码都是一行一行读入并运行的,但是对于函数来说,都是一次性读入,所以在上面的代码中,g()是被一次性读入的,并且解释器记住了g()定义了x=2,所以x就会引用到local scope中的变量x,但是x在使用前没有先声明(使用前必须先声明),所以出错。

#函数的两个例子

函数在声明定义阶段不会执行,因此可以使用未定义的名字,但是在运行之前,这些名字必须定义好,否则会出错。

x=1
def f():x=3g()print("f:",x)   # 3def g():print("g:",x)   # 1f()print("main:",x)    # 1

这里不会出错,因为在运行之前,我们已经定义了g()。

x=1
def f():x=3g()print("f:",x)f()   # 报错def g():print("g:",x) 

这里出错,这是因为f()已经运行了,但是g()还没有定义好,所以就出错了。

python的名字空间(namespace)与作用域(scope)相关推荐

  1. c++ 名字空间 namespace

    定义 namespace 名字空间的名字{ 全局变量 类型定义 函数 } 意义 对于一个较大型的C++程序来说,需要由多个程序员相互协作编写,这样的情况下容易出现不同程序员在需要负责的程序部分使用相同 ...

  2. C++ 名字空间(namespace)

    C++支持多种作用域:全局域.局部域.块域.类域,还有名字空间域等. 作用域:规定变量能够被访问的范围,离开这个范围的变量不能被访问. 作用域是一个独立的地盘,让变量不会暴露出去,也就是说作用域最大的 ...

  3. 名字空间(namespace)

    作用:缓解名字污染. 访问名字空间内成员.类的三种方式: 1.名字空间别名 namespace International_Business_Machines { int a; .... } //别名 ...

  4. C++引入名字空间(namespace)意义何在?为什么using namespace std会成为常用语句?

    在没有引入名字空间的概念之前,用户在一个cpp文件(即用C或C++代码写的源码文件)的开始位置一般会引入头文件,比如<stdio.h>,这里面就有已经定义好的全局变量.函数名.和类名,如果 ...

  5. c++ 静态类成员函数(static member function) vs 名字空间 (namespace)

    好多人喜欢把工具函数做成static member function.这样以增加隐蔽性和封装性,由其是从C#,java转而使用c++的开发人员. 例如: class my_math { public: ...

  6. python 作用域 前缀_Python 之作用域和名字空间

    作用域与名字空间 Python有一个核心概念是名字空间(namespace),namespace是一个name到object 的映射关系,Python有很多namespace,因此,在代码中如果碰到一 ...

  7. C++的名字空间(很重要)

    一.什么是名字空间? C++中对函数.变量.类型进行逻辑上的划分,避免同名的标识符重定义. 当我们在处理非常庞大复杂的项目时,不可避免地需要多人共同合作,可是人一多,取出来的名字难免重复,于是就会发生 ...

  8. c++之头文件基本输出,输入,名字空间,引用,内联函数,函数重载,缺省参数

    c++之头文件,基本输出,输入,名字空间,引用,内联函数,函数重载,缺省参数 文章目录 c++之头文件,基本输出,输入,名字空间,引用,内联函数,函数重载,缺省参数 前言 一.头文件,基本输出,输入 ...

  9. java schema名_关于Schema的名字空间

    基本的 XML Schema 的使用就是这样,下面我们要介绍 XML Schema 的另外一个核心的部分也是 Schema 最关键的一个部分,就是关于 Schema 的名字空间( namespace ...

最新文章

  1. python中的列表生成式_Python中的列表生成式
  2. eclipse新建maven项目_通过Eclipse新建简单动态项目,访问成功
  3. 机器学习中的训练集,验证集及测试集的关系
  4. mzy,struts学习(一)
  5. 日志服务接入方式之Unity 3D篇
  6. oracle 查询时间跨度一年,关于时间跨度比较的OVERLAPS函数
  7. 取文件 shell_webshell文件上传分析溯源
  8. Shiro框架原理及应用分析
  9. Python之网络编程(socketserver模块详解、链接认证)
  10. iOS之CATiledLayer的属性简介和使用
  11. c语言编写自由落体运动程序,3个C语言程序急求大神编写,再次先谢过了、
  12. 生物图像处理软件_细胞分割
  13. 电脑网页截长屏最简单的方法
  14. SAP 特殊字符的处理CL_ABAP_CHAR_UTILITIES(去除多余的换行符、换页符、Tab符)
  15. performSelector一系列方法调用和延时调用导致的内存泄露
  16. buuoj 小易的U盘
  17. Linux软件磁盘列阵RAID
  18. php微信银行卡rsa加密,如何使用微信公钥加密银行卡号和姓名
  19. Java流程控制相关知识(四)
  20. 微信开通检测软件的使用方法(入门教程)

热门文章

  1. iOS 15个人热点无法连接?10个修复技巧分享
  2. CF Round231C (ZWJ 神构造)
  3. c#在output窗口输出调试信息
  4. 腾讯最难lua面试题答案及解析
  5. 创建Direct3D9设备-------VB6编程学习DX9游戏编程DirectX9编程2D小游戏源码冷风引擎CoolWind2D游戏引擎(5)
  6. SrpingCloud系统学习 - 熔断机制
  7. Python爬虫:ZzzFun动漫视频网
  8. 函数 fseek() 使用说明
  9. ON_NOTIFY用法
  10. Python列表、元组、字典相关练习题记录——第三天