详解Python变量作用域

本文暂时不讨论类定义中的变量(成员)作用域,改天可能会单独成文介绍。

变量作用域总起来说可以这么理解:1)在函数内如果只引用某个变量的值而没有为其赋新值,该变量为(隐式的)全局变量;2)如果在函数内某条代码有为变量赋值的操作,该变量从此之后就被认为是(隐式的)局部变量,除非在函数内该代码之前显式地用关键字global进行了声明。

>>> def demo():

global x #声明或创建全局变量

x = 3 #修改全局变量的值

y =4 #局部变量

print(x, y)

>>> x = 5 #在函数外部定义了全局变量x

>>> demo() #本次调用修改了全局变量x的值

3 4

>>> x

3

>>> y #局部变量在函数运行结束之后自动删除

NameError: name 'y' is not defined

>>> del x #删除了全局变量x

>>> x

NameError: name 'x' is not defined

>>> demo() #本次调用创建了全局变量

3 4

>>> x

3

如果局部变量与全局变量具有相同的名字,那么该局部变量会在自己的作用域内隐藏同名的全局变量,例如下面的代码所演示。

>>> def demo():

x = 3 #创建了局部变量,并自动隐藏了同名的全局变量

print(x)

>>> x = 5 #创建全局变量

>>> x

5

>>> demo()

3

>>> x #函数调用结束后,不影响全局变量x的值

5

除了局部变量和全局变量,Python还支持使用nonlocal关键字定义一种介于二者之间的变量。例如下面的代码:

def scope_test():

def do_local():

spam = "我是局部变量"

def do_nonlocal():

nonlocal spam #这时要求spam必须是已存在的变量

spam = "我不是局部变量,也不是全局变量"

def do_global():

global spam #如果全局作用域内没有spam,就自动新建一个

spam = "我是全局变量"

spam = "原来的值"

do_local()

print("局部变量赋值后:", spam)

do_nonlocal()

print("nonlocal变量赋值后:", spam)

do_global()

print("全局变量赋值后:", spam)

scope_test()

print("全局变量:", spam)

上面的代码运行结果为:

局部变量赋值后: 原来的值

nonlocal变量赋值后: 我不是局部变量,也不是全局变量

全局变量赋值后: 我不是局部变量,也不是全局变量

全局变量: 我是全局变量

思考题:如果有下面的类框架,要求把其中的pass替换为有效代码,实现并模拟数据结构中“双链表”,你会怎么写呢?明天会把我写的代码贴出来以便大家参考和对照,当然在这之前可以先参考一下【Python实现单链表】。

class Node:

'''双链表节点结构'''

def __init__(self, data, leftNode=None, rightNode=None):

#设置当前节点的值和指向下一个节点的指针

self.data = data

self.left = leftNode

self.right = rightNode

def insertAfter(self, node):

#在当前节点之后插入新节点node

pass

def insertBefore(self, node):

#在当前节点之前插入新节点node

pass

def deleteAfter(self):

#删除当前节点之后的节点

pass

def deleteBefore(self):

#删除当前节点之前的节点

pass

原文发布于微信公众号 - Python小屋(Python_xiaowu)

原文发表时间:2016-11-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏linux运维学习

linux学习第六十四篇:Shell脚本中的逻辑判断,文件目录属性判断, if特殊用法,case判断

Shell脚本中的逻辑判断 格式1:if 条件 ; then 语句; fi 格式2:if 条件; then 语句; else 语句; fi 格式3:if …; ...

33060
来自专栏java相关

Shell脚本编程

linux中的变量分为环境变量和普通变量,其中环境变量可以理解为全局变量,在所有shell的子程序中都可以引用,普通变量只能在自己的shell程序中使用,程序结...

24020
来自专栏数据结构与算法

3185 队列练习 1

3185 队列练习 1 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 给定一...

32160
来自专栏技术小站

编程填空:第i位替换 编程填空:第i位取反 编程填空:左边i位取反

写出函数中缺失的部分,使得函数返回值为一个整数,该整数的第i位和m的第i位相同,其他位和n相同。

24110
来自专栏JavaEdge

Java异常之IllegalMonitorStateExceptionJavaDoc解决方法:总结

Thrown to indicate that a thread has attempted to wait on an object's monitor or...

5930
来自专栏小樱的经验随笔

Javascript中的url编码与解码(详解)

摘要 本文主要针对URI编解码的相关问题做了介绍,对url编码中哪些字符需要编码、为什么需要编码做了详细的说明,并对比分析了Javascript中和编解码相关的...

45090
来自专栏互联网杂技

JS模块与命名空间的介绍

起因 将代码组织到类中的一个重要原因是让代码更加“模块化”,可以在很多不同的场景中实现代码的重用。但类不是唯一的模块化代码的方式。 一般来讲,模块是一个独立的J...

40460
来自专栏yl 成长笔记

深刻理解反射(Reflection)

最近公司在搞自动化测试,由于版权问题,无法用 ’录制脚本‘ 进行,也就没法用 VS 自带的 UITest 框架(蛋疼), 所以只能开源的 FlaUI 框架来搞了...

15740
来自专栏偏前端工程师的驿站

Velocity魔法堂系列二:VTL语法详解

一、前言                               Velocity作为历史悠久的模板引擎不单单可以替代JSP作为Java Web的服务端网页...

23750
来自专栏HTML5学堂

2015.12.17 HTML5真题练习

HTML5学堂:每天一道题,强壮程序员!今日主要涉及12.16日关于函数返回值的题目解答,以及一道涉及闭包的题目。 HTML5真题【2015.12.16】答案解...

28040

扫码关注云+社区

领取腾讯云代金券