python名称与作用域_Python变量命名与作用域的坑

function showImg(url) {

var frameid = 'frameimg' + Math.random();

window.img = '

document.write('');

}

使用python有些年头了,自认为对Python的基本知识很了解了,今天发生的一件事让我对Python有了更多的认识,写成文章做个记录。

同事让我帮忙看以下一段代码,具体内容和函数名字可以不用太过在意,命名上做了一些特殊处理,但是不影响代码逻辑和要表达的意思。

for循环中当node_type为fb时,将FBX对象返回并作为全局变量dut(node_name的内容是字符串dut),接下来print dut,报错。

def setup_module(module):

with step('Set_setup'):

function_1_run(topo_info)

function_2_run(topo_info)

function_3_run(topo_info, set_resource, 'device_config')

for node in topo_info.nodes:

if node.type == 'fb':

globals()[node.name] = FBX(node.manage_ip,'admin','111111')

print node.name

print globals()[node.name]

print dut

else:

globals()[node.name] = Device()

globals()[node.name].node_info = node

if not get_config_file(topo_info, set_resource, 'device_config'):

test = dut

print test

with cli_ctx(dut) as dut:

dut.cli.cmd_list = \

[

'configure',

'interface fastEthernet 2',

'ip address 192.168.1.5/24'

]

dut.cli.exec_cmd()

log.info('cli_ctx 1 end')

export_firebox_topo(topo_info, set_resource, 'device_config')

错误信息如下:

==================================== ERRORS ====================================

___________________ ERROR at setup of some_module_1 ___________________

module =

def setup_module(module):

with step('Set_setup'):

function_1_run(topo_info)

function_2_run(topo_info)

function_3_run(topo_info, set_resource, 'device_config')

for node in topo_info.nodes:

if node.type == 'fb':

globals()[node.name] = FBX(node.manage_ip,'admin','111111')

print node.name

print globals()[node.name]

> print dut

E UnboundLocalError: local variable 'dut' referenced before assignment

some_name_python.py:54: UnboundLocalError

========================== 1 error in 155.62 seconds ===========================

同事提到,如果将with cli_ctx as dut这个block删除掉,代码执行正常。

听到这里,我的第一反应是变量作用域的问题,但是也无法道出其中原委,于是建议同事,将context manager那一段代码改成with cli_ctx as d,重新尝试一下是否有问题,同时我在网上继续搜索相关的原因,之后由结果和理论结合分析问题的原因。

幸运的是,代码修改以后,执行正常,我也找到了一些文章来解释这个问题,我的第一感觉也没有错,的确是变量作用域的问题,代码在执行过程中,print dut实际上是在访问Local variable,而不是我们期望的global variable dut。

参考Python的官方文档和搜索到的资料,总结出具体原因如下。

当搜索一个变量的时候,先从局部作用域开始搜索,如果在局部作用域没有找到那个变量,就会在全局变量中找这个变量,如果找不到抛出异常Unbound-LocalError。

如果内部函数有引用外部函数的同名变量或者全局变量,并且对这个变量有修改,那么python会认为它是一个局部变量。因为对变量的定义在代码块以外,当前代码块中没有变量的定义和赋值,所以报错。

在我们的代码中,全局变量dut虽然创建了,但是由于在函数代码块中,下文中有context manager cli_ctx对变量dut进行了赋值操作,导致在函数block中,dut成为了局部变量,而非全局变量。

对变量赋值的操作=是很明显的语句,其他不是那么明显的赋值操作有:for循环中的赋值,except语句中的赋值,with...as...{var}中的var。

大坑啊,基础不够牢靠还是。

Reference

Python 2.7.13 Documentation - Language Reference - 4. Execution Model

Stackoverflow - Short Description of the Scoping Rules?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/355411.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2017.0613.《计算机组成原理》总线控制-通信控制

同步通信控制 1.同步通信控制中,总线的传输周期的时间长是大于时钟周期的。怎么来理解这个,时钟是数字电路中,控制着信号的每次传输,很短暂,但是总线的传输周期很长, 因为其中涉及很多操作。 2.整个传输周期…

EAP 7 Alpha和Java EE 7入门

红帽JBoss企业应用程序平台7(JBoss EAP 7)是基于开放标准构建并符合Java Enterprise Edition 7规范的中间件平台。 它基于WildFly等经过验证的创新开源技术之上,它将使Java EE 7的开发变得更加容易。 这是有关如何开始使用最新ALPHA版本的快速…

简单点赞效果html,js实现点赞效果

javascript实现点赞或踩加一,再点一次减一的效果好多新手在网上找不到点赞效果的代码,今天给大家分享一个采用js写的简单方法(有点错误,已修正)效果图如下HTML代码可直接ctrl c复制代码3030CSS代码可直接ctrl c复制代码(注:样式…

python切割图像,使用Python图像库将一个图像切割成多个图像

I need to cut this image into three parts using PIL and pick the middle part.How do I do it?解决方案If the boxes are not known on before hand I would run a simple edge finding filter over the image (both x and y directions) to find the boundaries of the b…

html显示和隐藏不占空间的是什么,css怎么设置不占用空间的隐藏?

css怎么设置不占用空间的隐藏?下面本篇文章就来给大家介绍一下使用CSS设置不占用空间隐藏的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。在CSS中,可以利用display属性,设置display:none来设…

python相似图片识别_Python+Opencv识别两张相似图片

PythonOpencv识别两张相似图片在网上看到python做图像识别的相关文章后,真心感觉python的功能实在太强大,因此将这些文章总结一下,建立一下自己的知识体系。当然了,图像识别这个话题作为计算机科学的一个分支,不可能就…

Oracle学习

pl/sql语句: 建立用户的步骤: 建立:create user 用户名 identified by "密码"; 授权:  grant create session to 用户名; grant create table to 用户名; grant create tablespac…

javame_JavaME:Google静态地图API

javame无论您是需要基于位置的应用程序的地图还是只是出于娱乐目的,都可以使用有史以来最简单的方法:Google Static Maps API。 在这篇文章中,我们将看到如何从纬度和经度获得地图作为图像。 可以使用Location API获得纬度和经度,…

js如何获取html图片,JS/JQuery获取网页或文章或某DIV所有图片

要获取网页所有图片,我们可以通过Javascript就能轻松实现,不过要想获得文章或某容器(如:Div)里所有图片,使用JQuery而不是Javascript来实现就会变得更加简单。本文将给你详细介绍。通过Javascript获取网页所有图片html代码JS/JQue…

React Native的键盘遮挡问题(input/webview里)

2017-06-15 1:使用keyVoaidView来解决 注意要设置behavio“absolute”,哎。记性差 好像拼错了 2:使用下面的代码,监听键盘,然后将webView拉高就可以了 import React, { Component } from react; import { Keyboard, TextInput } from react…

带有Netflix Ribbon的Spring Cloud Rest Client-基础知识

在较早的博客文章中,我介绍了Spring Cloud世界中REST客户端的各种选项。 所有选项围绕着基于Netflix OSS的名为Ribbon的组件,该组件处理与承载服务的不同实例之间的调用负载平衡,处理故障转移,超时等有关的方面。在此,…

html中给文章怎么设置行高,css如何设置行距?

在网页的布局中几大段文字挤在一起总归是不好看的,这时候我们就需要来设置行间距来让文字看起来不拥挤,也让整个页面看起来美观整洁,那么,行间距该如何设置呢?本篇文章就来给大家介绍一下css行间距的设置方法。首先我们…

初中数学知识点总结_初中物理 | 最全知识点总结

往期回顾初中物理 | 知识点总结一:机械运动初中物理 | 知识点总结二:声现象初中物理 | 知识点总结三:物态变化初中物理 | 知识点总结四:光现象初中物理 | 知识点总结五:透镜及其应用初中物理 | 知识点总结六&#xff1…

redis版本_全球首发|阿里云正式推出云数据库Redis6.0版本

Redis 6.0更多精彩详情2020年6月23日,阿里云正式推出云数据库Redis 6.0版本。Redis 6.0版本为Redis开源社区于5月2日发布的全新版本,包含多项重大功能更新和大幅度的性能提升。依托于阿里云强大的云服务与管控能力,以及团队的快速跟进&#x…

webclient无法获取html文件,C# WebClient获取网页源码的方法

效果如图完整代码如下using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;//引入以下命名空间using System.Net;using System.IO;using System.Threading;name…

AFNetworking到底做了什么?

http://www.cocoachina.com/ios/20161209/18277.html转载于:https://www.cnblogs.com/zxykit/p/7018411.html

基于javafx的五子棋_基于JavaFX的SimpleDateFormat演示程序

基于javafx的五子棋对于使用Java Date进行格式化的新手,甚至对于使用Java Date进行格式化的新手,对于有经验的Java开发人员来说,可能都会有些棘手,其中之一就是使用SimpleDateFormat指定日期/时间格式。 SimpleDateFormat的基于类…

监督分类空白处也被分类了_监督学习(2)|本质是分类的“逻辑回归”

引言机器学习,绕不开预测问题,预测绕不开回归和分类。本篇介绍最常用的二分类算法:逻辑回归(Logistics Regression),当然随着算法的发展,它也可用于多分类问题。每一个算法都是许许多多数学家的努力铸就,理…

html网页制作图案,巧用CSS滤镜做图案文字-网页设计,HTML/CSS

请先看看以下演示中的图案文字。这可不是图片效果,而是用css滤镜中的chroma() 语句做成的文本文字,其中文本的内容和图案都可以自由设定。先介绍一下这个神奇的滤镜:chroma() 滤镜。语法: filter:chroma( color#cccccc) &#xff…

关于msbuild 编译.net 4.5新语法错误的解决方法

.net4.5以前msbuild 是在%windir%/Microsoft.NET/FrameworkXX/vXX目录下,如:C:\Windows\Microsoft.NET\Framework64\v4.0.30319,不过在使用4.5新语法后就无法编译通过,这时候就应该使用vs自带msbuild ,路径如下C:\Program Files (…