名字空间(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. js判断字符串包含某个字符_python判断字符串以什么开始
  2. C++ public、protected、private区别
  3. char与byte的区别
  4. 扫地机器人狗毛_扫地机器人:我是清理狗毛的!不是清理狗屎的!
  5. 小程序引入的echarts过大如何解决_解决生鲜行业“获客难”的难题,教你如何妙用小程序...
  6. fetch 不是xhr_春招|前端2019应届春招:不是被大厂选,而是选大厂(字节跳动,美团,网易)...
  7. DOCKER基础技术:LINUX NAMESPACE(上)
  8. Android自定义选座,Android实现电影院选座效果
  9. 设计模式 - 建造者模式/生成器模式
  10. java浏览器控件jxbrowser(简单demo模拟自动登录与点击)
  11. 里程碑!美国航天局NASA耗资高达百亿美元,“终极太空望远镜”拍到了什么?| 美通社头条...
  12. .lib不是有效的Win32应用程序
  13. 词根词缀|ori/orn/ortho/pact/pan及词源O的故事
  14. vue 过滤器做字数限制并显示省略号
  15. 简易凯撒密码实现,很容易
  16. statusbar 尺寸 显示图标_CAD状态栏图标显示状态的设置方法步骤
  17. linux系统搭建论坛,Linux下搭建discuz论坛
  18. Windows 编程中的数据类型(转自:维基百科)
  19. 云计算专业怎么样,大学应届生学的话难不难?
  20. 使用Python requests和BeautifulSoup库爬取去哪儿网

热门文章

  1. java pdf_Java 生成 PDF 文档
  2. Oracle Reports 6i培训教程 - 百度文库
  3. 昔人已乘黄鹤去 此地空余黄鹤楼-崔颢
  4. C++使用CreateProcess执行cmd命令(实例演示)
  5. 记录第一次开发android的学习心得
  6. ADXL345知识学习总结
  7. 单元测试|unittest生成测试报告
  8. UDP可靠传输,UDT和UDX协议比较
  9. ADF 单位根检验 Dickey-Fuller 迪基-福勒检验
  10. java中String优化之intern()方法