日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

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

發(fā)布時(shí)間:2023/12/2 python 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python名称与作用域_Python变量命名与作用域的坑 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

function showImg(url) {

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

window.img = '

document.write('');

}

使用python有些年頭了,自認(rèn)為對Python的基本知識(shí)很了解了,今天發(fā)生的一件事讓我對Python有了更多的認(rèn)識(shí),寫成文章做個(gè)記錄。

同事讓我?guī)兔匆韵乱欢未a,具體內(nèi)容和函數(shù)名字可以不用太過在意,命名上做了一些特殊處理,但是不影響代碼邏輯和要表達(dá)的意思。

for循環(huán)中當(dāng)node_type為fb時(shí),將FBX對象返回并作為全局變量dut(node_name的內(nèi)容是字符串dut),接下來print dut,報(bào)錯(cuò)。

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')

錯(cuò)誤信息如下:

==================================== 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這個(gè)block刪除掉,代碼執(zhí)行正常。

聽到這里,我的第一反應(yīng)是變量作用域的問題,但是也無法道出其中原委,于是建議同事,將context manager那一段代碼改成with cli_ctx as d,重新嘗試一下是否有問題,同時(shí)我在網(wǎng)上繼續(xù)搜索相關(guān)的原因,之后由結(jié)果和理論結(jié)合分析問題的原因。

幸運(yùn)的是,代碼修改以后,執(zhí)行正常,我也找到了一些文章來解釋這個(gè)問題,我的第一感覺也沒有錯(cuò),的確是變量作用域的問題,代碼在執(zhí)行過程中,print dut實(shí)際上是在訪問Local variable,而不是我們期望的global variable dut。

參考Python的官方文檔和搜索到的資料,總結(jié)出具體原因如下。

當(dāng)搜索一個(gè)變量的時(shí)候,先從局部作用域開始搜索,如果在局部作用域沒有找到那個(gè)變量,就會(huì)在全局變量中找這個(gè)變量,如果找不到拋出異常Unbound-LocalError。

如果內(nèi)部函數(shù)有引用外部函數(shù)的同名變量或者全局變量,并且對這個(gè)變量有修改,那么python會(huì)認(rèn)為它是一個(gè)局部變量。因?yàn)閷ψ兞康亩x在代碼塊以外,當(dāng)前代碼塊中沒有變量的定義和賦值,所以報(bào)錯(cuò)。

在我們的代碼中,全局變量dut雖然創(chuàng)建了,但是由于在函數(shù)代碼塊中,下文中有context manager cli_ctx對變量dut進(jìn)行了賦值操作,導(dǎo)致在函數(shù)block中,dut成為了局部變量,而非全局變量。

對變量賦值的操作=是很明顯的語句,其他不是那么明顯的賦值操作有:for循環(huán)中的賦值,except語句中的賦值,with...as...{var}中的var。

大坑啊,基礎(chǔ)不夠牢靠還是。

Reference

Python 2.7.13 Documentation - Language Reference - 4. Execution Model

Stackoverflow - Short Description of the Scoping Rules?

總結(jié)

以上是生活随笔為你收集整理的python名称与作用域_Python变量命名与作用域的坑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。