Python Scopes and Namespaces

Before introducing classes, I first have to tell you something about Python’s scope rules. Class definitions play some neat tricks with namespaces, and you need to know how scopes and namespaces work to fully understand what’s going on. Incidentally, knowledge about this subject is useful for any advanced Python programmer.

Let’s begin with some definitions.

namespace is a mapping from names to objects. Most namespaces are currently implemented as Python dictionaries, but that’s normally not noticeable in any way (except for performance), and it may change in the future. Examples of namespaces are: the set of built-in names (containing functions such as abs(), and built-in exception names); the global names in a module; and the local names in a function invocation. In a sense the set of attributes of an object also form a namespace. The important thing to know about namespaces is that there is absolutely no relation between names in different namespaces; for instance, two different modules may both define a function maximize without confusion — users of the modules must prefix it with the module name.

By the way, I use the word attribute for any name following a dot — for example, in the expression z.realreal is an attribute of the object z. Strictly speaking, references to names in modules are attribute references: in the expression modname.funcnamemodname is a module object and funcname is an attribute of it. In this case there happens to be a straightforward mapping between the module’s attributes and the global names defined in the module: they share the same namespace![1]

Attributes may be read-only or writable. In the latter case, assignment to attributes is possible. Module attributes are writable: you can write modname.the_answer = 42. Writable attributes may also be deleted with the del statement. For example, del modname.the_answer will remove the attribute the_answer from the object named bymodname.

Namespaces are created at different moments and have different lifetimes. The namespace containing the built-in names is created when the Python interpreter starts up, and is never deleted. The global namespace for a module is created when the module definition is read in; normally, module namespaces also last until the interpreter quits. The statements executed by the top-level invocation of the interpreter, either read from a script file or interactively, are considered part of a module called __main__, so they have their own global namespace. (The built-in names actually also live in a module; this is called builtins.)

The local namespace for a function is created when the function is called, and deleted when the function returns or raises an exception that is not handled within the function. (Actually, forgetting would be a better way to describe what actually happens.) Of course, recursive invocations each have their own local namespace.

scope is a textual region of a Python program where a namespace is directly accessible. “Directly accessible” here means that an unqualified reference to a name attempts to find the name in the namespace.

Although scopes are determined statically, they are used dynamically. At any time during execution, there are at least three nested scopes whose namespaces are directly accessible:

  • the innermost scope, which is searched first, contains the local names
  • the scopes of any enclosing functions, which are searched starting with the nearest enclosing scope, contains non-local, but also non-global names
  • the next-to-last scope contains the current module’s global names
  • the outermost scope (searched last) is the namespace containing built-in names

If a name is declared global, then all references and assignments go directly to the middle scope containing the module’s global names. To rebind variables found outside of the innermost scope, the nonlocal statement can be used; if not declared nonlocal, those variable are read-only (an attempt to write to such a variable will simply create a new local variable in the innermost scope, leaving the identically named outer variable unchanged).

Usually, the local scope references the local names of the (textually) current function. Outside functions, the local scope references the same namespace as the global scope: the module’s namespace. Class definitions place yet another namespace in the local scope.

It is important to realize that scopes are determined textually: the global scope of a function defined in a module is that module’s namespace, no matter from where or by what alias the function is called. On the other hand, the actual search for names is done dynamically, at run time — however, the language definition is evolving towards static name resolution, at “compile” time, so don’t rely on dynamic name resolution! (In fact, local variables are already determined statically.)

A special quirk of Python is that – if no global statement is in effect – assignments to names always go into the innermost scope. Assignments do not copy data — they just bind names to objects. The same is true for deletions: the statement del x removes the binding of x from the namespace referenced by the local scope. In fact, all operations that introduce new names use the local scope: in particular, import statements and function definitions bind the module or function name in the local scope.

The global statement can be used to indicate that particular variables live in the global scope and should be rebound there; the nonlocal statement indicates that particular variables live in an enclosing scope and should be rebound there.

This is an example demonstrating how to reference the different scopes and namespaces, and how global and nonlocal affect variable binding:

def scope_test():
    def do_local():
        spam = "local spam"
    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"
    def do_global():
        global spam
        spam = "global spam"
    spam = "test spam"
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)

The output of the example code is:

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

Note how the local assignment (which is default) didn’t change scope_test‘s binding of spam. The nonlocal assignment changed scope_test‘s binding of spam, and the global assignment changed the module-level binding.

You can also see that there was no previous binding for spam before the global assignment.

时间: 2024-08-24 01:47:23

Python Scopes and Namespaces的相关文章

Python 2.7.8 学习笔记(001)python manuals/the python tutorial

从今天开始学python, python有点意思,第一感觉界面和matlab有点像. 手头没有什么资料,就从安装好了的一个python 2.7.8,里面有个英文版的manual,那就只好从这里开始吧,为什么不是中文版的呢??那就边看边翻译吧. python漫游指南:python是一种简单易学功能强大的编程语言.它有高效的数据结构和简单但有效的面向对象编程方法.python优雅的语法和动态拼写以及解释特性,使得它在许多平台上成为一种理想的脚本语言和快速程序开发工具. python的解释器和扩展标准

Python:闭包

闭包(Closure) 在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是引用了自由变量的函数.这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外. 命名空间与作用域 我们可以把命名空间看做一个大型的字典类型(Dict),里面包含了所有变量的名字和值的映射关系.在 Python 中,作用域实际上可以看做是"在当前上下文的位置,获取命名空间变量的规则".在 Python

Python 作用域和命名空间

Python Scopes and Namespaces A namespace is a mapping from names to objects. 命名空间是一个从名字到对象的映射(指向,明确的路径). Most namespaces are currently implemented as Python dictionaries. 大部分都是由字典dict(其他语言也称为hash)实现. 例子: the set of built-in names .放置内置函数的集合.模块中的全局名称:

Apache Calcite 学习 (一)

关于 Apache Calcite 的简单介绍可以参考 Apache Calcite:Hadoop 中新型大数据查询引擎 这篇文章,Calcite 一开始设计的目标就是 one size fits all,它希望能为不同计算存储引擎提供统一的 SQL 查询引擎,当然 Calcite 并不仅仅是一个简单的 SQL 查询引擎,在论文 Apache Calcite: A Foundational Framework for Optimized Query Processing Over Heterog

python小技巧(转)

http://blog.jobbole.com/63320/ 30 Python Language Features and Tricks You May Not Know About Posted on Mar 05, 2014 , last modified on May 19, 2014 - Permanent link 1   Introduction Since I started learning Python, I decided to maintain an often visi

Python中的类(classes)

Python的类机制使用尽可能少的新语法和语义将类引入语言.python的类提供了面向对象程序设计语言所有的 标准特性:类继承机制允许有多个基类,一个派生类可以覆盖基类中的任何方法,一个方法可以使用相同的名字调用 基类中的方法. Table of Contents 1 名字和对象 2 Python的域(scopes)和名称空间(namespaces) 3 初识类 3.1 定义类 3.2 类对象 3.3 实例化对象 3.4 方法对象 4 漫谈 5 派生 6 多重继承 7 私有变量和类局部引用 8

python中eval, exec, execfile,和compile

eval(str [,globals [,locals ]])函数将字符串str当成有效Python表达式来求值,并返回计算结果. 同样地, exec语句将字符串str当成有效Python代码来执行.提供给exec的代码的名称空间和exec语句的名称空间相同. 最后,execfile(filename [,globals [,locals ]])函数可以用来执行一个文件,看下面的例子: >>> eval('3+4') 7 >>> exec 'a=100' >>

【Python笔记】Python的几个高级语法概念浅析:lambda表达式 && 闭包 && 装饰器

本文主要记录自己对几个高级语法概念的理解:匿名函数.lambda表达式.闭包.装饰器. 这几个概念并非Python特有,但本文只限于用Python做说明. 1. 匿名函数 匿名函数(anonymous function)是指未与任何标识符绑定的函数,多用在functional programming languages领域,典型应用场合: 1) 作为参数传给高阶函数(higher-order function ),如python中的built-in函数filter/map/reduce都是典型的

python基础学习11(核心编程第二版)部分

# -*- coding: utf-8 -*- # ==================== #File: python #Author: python #Date: 2014 #==================== __author__ = 'Administrator' #执行环境 #可调用对象 """ 许多的python 对象都是我们所说的可调用的,即是任何能通过函数操作符“()”来调用的对象.要调用可调用对象, 函数操作符得紧跟在可调用对象之后.Python 有4