看python官方说明学python-class-object-类、对象-之区域和名空间

9.2. 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 functionmaximize 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 delstatement. For example, del modname.the_answer will remove the attribute the_answer from the object named by modname.

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.Torebind variables found outside of the innermost scope, the nonlocal statement can be used;

(解释下面例子中输出

After nonlocal assignment: nonlocal spam

的原因)

if not declared nonlocal, thosevariable are read-only(an attempt to write to such a variable will simply create anew local variable in the innermost scope, leaving the identically named outer variable unchanged).(解释下面例子中输出

After local assignment: test spam
的原因)

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. (有助于理解python中所有东西都是对象)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.

9.2.1. Scopes and Namespaces Example

This is an example demonstrating how to reference the different scopes and namespaces, and how global andnonlocal 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        #在这里global的话直接就会生成一个spam的变量,也是最后一行能print出spam值的原因
        spam = "global spam"

    spam = "test spam"
    do_local()                         #这里,此函数的spam = "local spam"并不能将变量的值传出所定义的函数do_local()之外spam只能在 do_local() 的local scope本地区域里面使用,不能外传
    print("After local assignment:", spam) #这里spam的值接受不到do_local()中赋的值,只能用spam以前被赋的值
    do_nonlocal()                       #nonlocal 处理过的 spam,可以让其外面来取值,形成关系,文中所说的rebound的意思
    print("After nonlocal assignment:", spam) #这时候可以放心的取值了  :D
    do_global()                    # 经过global的spam,“能耐大了”,直接到最外层了,内层都不管了。。。 
    print("After global assignment:", spam) #这里经过global后的变量spam不能在内层输出,所以主函数中spam是还是上次别的操作赋的值

scope_test()
print("In global scope:", spam)   #由于global 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 nonlocalassignment 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.


++++++++++++++++++++++++

总结一下:


local 的话,跟虚参差不多,只能本地用,不能拿出去。很保守

nonlocal 比虚参嚣张一点,可以稍微往外跳一层外但是不能全局用(但如果一层就到天就能全局了)。是那种有点能耐,小得瑟那种。

global 是最得意忘形的,本事最大,直接跳出到最外层到天里面层的兄弟的还不能用只在最外层的赫赫有名

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值