设为首页 收藏本站
查看: 830|回复: 0

[经验分享] python变量作用域

[复制链接]

尚未签到

发表于 2015-4-24 10:03:19 | 显示全部楼层 |阅读模式





























python变量作用域

  在python中,变量查找遵循LGB原则,即优先在局部作用域(local scope)中对变量进行查找,失败则在全局作用域(global scope)中进行查找,最后尝试再内建作用域(build-in scope)内查找,如果还是未找到的话,则抛出异常。后来由于闭包和嵌套函数的出现,作用域又增加了外部作用域,这样变量的查找作用域优先级变为:局部、外部、全局和内建。 作用域由def、class、lambda等语句产生,if、try、for等语句并不会产生新的作用域。我们看下面的一个例子:
  def scope1_f1():
    def f2():
        print local_v
    local_v = 'local'
    f2()
    print global_v
  if __name__ == "__main__":
    global_v = 'global'
    scope1_f1()
  在scope1_f1函数中我们并未对global_str进行赋值(即scope1_f1的局部作用域中并不存在变量lobal_str),但程序正常输出结果'local'和'global'。

一 局部作用域中不应对全局变量进行赋值
   需要注意的是虽然我们可以在函数中对全局的变量进行访问,但一旦局部作用域中对全局变量进行了赋值操作,python解释器就不会从全局作用域中查找,而会抛出UnboundLocalError错误。该规则在由局部作用域向外部作用域查找时同样有效。
def scope1_f1():
    print global_v
    global_v = 'local'
  if __name__ == "__main__":
    global_v = 'global'
    scope1_f1()
   运行程序我们会得到:UnboundLocalError: local variable 'global_v' referenced before assignment
  有资料将该规则描述为“局部作用域中全局变量应是只读”是不准确的。因为如果变量为list等类型,我们可以通过append这样的方法来修改全局变量,而不影响局部作用域对变量的访问。
def scope1_f1():
    print global_v
    global_v.add('local')
  if __name__ == "__main__":
    global_v = ['global']
    scope1_f1()
  二 局部作用域中使用 global实现对全局变量进行赋值
    如果说确实需要对全局变量进行赋值的话,应在局部作用域中使用global来修饰变量。python2.6中global对变量的修饰可以在函数的任意地方进行,但如果global在赋值之后的话,解释器会提示SyntaxWarning 。
def scope1_f1():
    global global_v
    print global_v
    global_v = 'local'
  if __name__ == "__main__":
    global_v = 'global'
    scope1_f1()
  三 继承类优先使用第一个基类中的变量
   在没有对变量初始化的情况下,继承类会优先使用第一个基类中的变量。下面的例子会输出1而不是2。(说明:如果继承类为初始化函数,会优先调第一个基类的初始化函数,如果前面的基类都没有的话才会调后面基类的初始化函数,初始化函数对变量的修改不在本文讨论范围),
class sclass1():
    a = 1
    def run(self):
        print self.a
class sclass2():
    a = 2
    def run(self):
        print self.a
  class dclass(sclass1, sclass2):
    def run(self):
        print self.a
  if __name__ == "__main__":
    a = dclass()
    a.run()  
  四 全局作用域指的是本模块而不是程序
   在变量查找时只会在本模块范围内进行变量的查找,即使使用from xxx import *也不会垮模块查找。在python中导入一个模块可以理解为是将另外一个模块各变量赋值给当前模块的同名变量, 对当前模块中变量的赋值不会影响到导入模块的变量。
main.py
from module2 import *
if __name__ == "__main__":
   module2_v = 5
   module2_v1 = 3
   print_modul2()
  modul2.py
module2_v1 = 'module2'
def print_modul2():
   print module2_v1
   print module2_v  
  在python中一切都是对象和变量,因此对函数、模块等的的查找同样遵循上面的规则。
   最后还存在的一个问题是:使用global可以再局部作用域中对全局变量赋值,那么如何在局部作用域中对外部变量赋值呢? 目前除了使用list这样的引用传递外我还没发现其他解决方法,留在这里大家一起思考吧。
  

  转载自:http://hi.baidu.com/kanif/item/8c0947ece7cfaad4ea34c997

python变量作用域

  在python中,变量查找遵循LGB原则,即优先在局部作用域(local scope)中对变量进行查找,失败则在全局作用域(global scope)中进行查找,最后尝试再内建作用域(build-in scope)内查找,如果还是未找到的话,则抛出异常。后来由于闭包和嵌套函数的出现,作用域又增加了外部作用域,这样变量的查找作用域优先级变为:局部、外部、全局和内建。 作用域由def、class、lambda等语句产生,if、try、for等语句并不会产生新的作用域。我们看下面的一个例子:
  def scope1_f1():
    def f2():
        print local_v
    local_v = 'local'
    f2()
    print global_v
  if __name__ == "__main__":
    global_v = 'global'
    scope1_f1()
  在scope1_f1函数中我们并未对global_str进行赋值(即scope1_f1的局部作用域中并不存在变量lobal_str),但程序正常输出结果'local'和'global'。

一 局部作用域中不应对全局变量进行赋值
   需要注意的是虽然我们可以在函数中对全局的变量进行访问,但一旦局部作用域中对全局变量进行了赋值操作,python解释器就不会从全局作用域中查找,而会抛出UnboundLocalError错误。该规则在由局部作用域向外部作用域查找时同样有效。
def scope1_f1():
    print global_v
    global_v = 'local'
  if __name__ == "__main__":
    global_v = 'global'
    scope1_f1()
   运行程序我们会得到:UnboundLocalError: local variable 'global_v' referenced before assignment
  有资料将该规则描述为“局部作用域中全局变量应是只读”是不准确的。因为如果变量为list等类型,我们可以通过append这样的方法来修改全局变量,而不影响局部作用域对变量的访问。
def scope1_f1():
    print global_v
    global_v.add('local')
  if __name__ == "__main__":
    global_v = ['global']
    scope1_f1()
  二 局部作用域中使用 global实现对全局变量进行赋值
    如果说确实需要对全局变量进行赋值的话,应在局部作用域中使用global来修饰变量。python2.6中global对变量的修饰可以在函数的任意地方进行,但如果global在赋值之后的话,解释器会提示SyntaxWarning 。
def scope1_f1():
    global global_v
    print global_v
    global_v = 'local'
  if __name__ == "__main__":
    global_v = 'global'
    scope1_f1()
  三 继承类优先使用第一个基类中的变量
   在没有对变量初始化的情况下,继承类会优先使用第一个基类中的变量。下面的例子会输出1而不是2。(说明:如果继承类为初始化函数,会优先调第一个基类的初始化函数,如果前面的基类都没有的话才会调后面基类的初始化函数,初始化函数对变量的修改不在本文讨论范围),
class sclass1():
    a = 1
    def run(self):
        print self.a
class sclass2():
    a = 2
    def run(self):
        print self.a
  class dclass(sclass1, sclass2):
    def run(self):
        print self.a
  if __name__ == "__main__":
    a = dclass()
    a.run()  
  四 全局作用域指的是本模块而不是程序
   在变量查找时只会在本模块范围内进行变量的查找,即使使用from xxx import *也不会垮模块查找。在python中导入一个模块可以理解为是将另外一个模块各变量赋值给当前模块的同名变量, 对当前模块中变量的赋值不会影响到导入模块的变量。
main.py
from module2 import *
if __name__ == "__main__":
   module2_v = 5
   module2_v1 = 3
   print_modul2()
  modul2.py
module2_v1 = 'module2'
def print_modul2():
   print module2_v1
   print module2_v  
  在python中一切都是对象和变量,因此对函数、模块等的的查找同样遵循上面的规则。
   最后还存在的一个问题是:使用global可以再局部作用域中对全局变量赋值,那么如何在局部作用域中对外部变量赋值呢? 目前除了使用list这样的引用传递外我还没发现其他解决方法,留在这里大家一起思考吧。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-60207-1-1.html 上篇帖子: python os模块总结 下篇帖子: 关于Python当前路径
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表