{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 作用域" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "在函数中,`Python` 从命名空间中寻找变量的顺序如下:\n", "\n", "- `local function scope`\n", "- `enclosing scope`\n", "- `global scope`\n", "- `builtin scope`\n", "\n", "例子:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# local 作用域" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def foo(a,b):\n", " c = 1\n", " d = a + b + c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这里所有的变量都在 `local` 作用域。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## global 作用域" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "c = 1\n", "def foo(a,b):\n", " d = a + b + c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这里的 `c` 就在 `global` 作用域。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## global 关键词" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "使用 `global` 关键词可以在 `local` 作用域中修改 `global` 作用域的值。" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n" ] } ], "source": [ "c = 1\n", "def foo():\n", " global c\n", " c = 2\n", " \n", "print c\n", "foo()\n", "print c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "其作用是将 `c` 指向 `global` 中的 `c`。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "如果不加关键词,那么 `local` 作用域的 `c` 不会影响 `global` 作用域中的值:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "1\n" ] } ], "source": [ "c = 1\n", "def foo():\n", " c = 2\n", " \n", "print c\n", "foo()\n", "print c" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## built-in 作用域" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3\n" ] } ], "source": [ "def list_length(a):\n", " return len(a)\n", "\n", "a = [1,2,3]\n", "print list_length(a)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这里函数 `len` 就是在 `built-in` 作用域中:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import __builtin__\n", "\n", "__builtin__.len" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## class 中的作用域" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Global | MyClass\n", "---|---\n", "`var = 0`
`MyClass`
`access_class` | `var = 1`
`access_class` " ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# global\n", "var = 0\n", "\n", "class MyClass(object):\n", " # class variable\n", " var = 1\n", " \n", " def access_class_c(self):\n", " print 'class var:', self.var\n", " \n", " def write_class_c(self):\n", " MyClass.var = 2\n", " print 'class var:', self.var\n", " \n", " def access_global_c(self):\n", " print 'global var:', var\n", " \n", " def write_instance_c(self):\n", " self.var = 3\n", " print 'instance var:', self.var" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Global | MyClass | obj\n", "---|---|----\n", "`var = 0`
`MyClass`
[`access_class`]
`obj` | `var = 1`
`access_class` |" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "obj = MyClass()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "查询 `self.var` 时,由于 `obj` 不存在 `var`,所以跳到 MyClass 中:\n", "\n", "Global | MyClass | obj\n", "---|---|----\n", "`var = 0`
`MyClass`
[`access_class`
`self`]
`obj` | `var = 1`
`access_class` |" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "class var: 1\n" ] } ], "source": [ "obj.access_class_c()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "查询 `var` 直接跳到 `global` 作用域:\n", "\n", "Global | MyClass | obj\n", "---|---|----\n", "`var = 0`
`MyClass`
[`access_class`
`self`]
`obj` | `var = 1`
`access_class` |" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "global var: 0\n" ] } ], "source": [ "obj.access_global_c()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "修改类中的 `MyClass.var`:\n", "\n", "Global | MyClass | obj\n", "---|---|----\n", "`var = 0`
`MyClass`
[`access_class`
`self`]
`obj` | `var = 2`
`access_class` |" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "class var: 2\n" ] } ], "source": [ "obj.write_class_c()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "修改实例中的 `var` 时,会直接在 `obj` 域中创建一个:\n", "\n", "Global | MyClass | obj\n", "---|---|----\n", "`var = 0`
`MyClass`
[`access_class`
`self`]
`obj` | `var = 2`
`access_class` | `var = 3`" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false, "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "instance var: 3\n" ] } ], "source": [ "obj.write_instance_c()" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false, "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "MyClass.var" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`MyClass` 中的 `var` 并没有改变。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 词法作用域" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "对于嵌套函数:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a = 1\n" ] } ], "source": [ "def outer():\n", " a = 1\n", " def inner():\n", " print \"a =\", a\n", " inner()\n", " \n", "outer()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "如果里面的函数没有找到变量,那么会向外一层寻找变量,如果再找不到,则到 `global` 作用域。\n", "\n", "返回的是函数的情况:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "a (1): 1\n" ] } ], "source": [ "def outer():\n", " a = 1\n", " def inner():\n", " return a\n", " return inner\n", " \n", "func = outer()\n", "\n", "print 'a (1):', func()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "func() 函数中调用的 `a` 要从它定义的地方开始寻找,而不是在 `func` 所在的作用域寻找。" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }