成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Python變量命名與作用域的坑

amuqiao / 2322人閱讀

摘要:循環(huán)中當(dāng)為時(shí),將對(duì)象返回并作為全局變量的內(nèi)容是字符串,接下來(lái),報(bào)錯(cuò)。幸運(yùn)的是,代碼修改以后,執(zhí)行正常,我也找到了一些文章來(lái)解釋這個(gè)問(wèn)題,我的第一感覺(jué)也沒(méi)有錯(cuò),的確是變量作用域的問(wèn)題,代碼在執(zhí)行過(guò)程中,實(shí)際上是在訪問(wèn),而不是我們期望的。

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

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

for循環(huán)中當(dāng)node_typefb時(shí),將FBX對(duì)象返回并作為全局變量dut(node_name的內(nèi)容是字符串dut),接下來(lái)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í)行正常。

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

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

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

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

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

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

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

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

Reference

Python 2.7.13 Documentation - Language Reference - 4. Execution Model
Stackoverflow - Short Description of the Scoping Rules?

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/40662.html

相關(guān)文章

  • Python家國(guó)天下

    摘要:正如儒家經(jīng)典所闡述修身齊家治國(guó)平天下。除此之外,模塊還有如下最基本的屬性在一個(gè)模塊的全局空間里,有些屬性是全局起作用的,稱之為全局變量,而其它在局部起作用的屬性,會(huì)被稱為局部變量。 導(dǎo)讀:Python貓是一只喵星來(lái)客,它愛(ài)地球的一切,特別愛(ài)優(yōu)雅而無(wú)所不能的 Python。我是它的人類朋友豌豆花下貓,被授權(quán)潤(rùn)色與發(fā)表它的文章。如果你是第一次看到這個(gè)系列文章,那我強(qiáng)烈建議,請(qǐng)先看看它寫(xiě)的前...

    姘擱『 評(píng)論0 收藏0
  • Python家國(guó)天下

    摘要:正如儒家經(jīng)典所闡述修身齊家治國(guó)平天下。除此之外,模塊還有如下最基本的屬性在一個(gè)模塊的全局空間里,有些屬性是全局起作用的,稱之為全局變量,而其它在局部起作用的屬性,會(huì)被稱為局部變量。 導(dǎo)讀:Python貓是一只喵星來(lái)客,它愛(ài)地球的一切,特別愛(ài)優(yōu)雅而無(wú)所不能的 Python。我是它的人類朋友豌豆花下貓,被授權(quán)潤(rùn)色與發(fā)表它的文章。如果你是第一次看到這個(gè)系列文章,那我強(qiáng)烈建議,請(qǐng)先看看它寫(xiě)的前...

    felix0913 評(píng)論0 收藏0
  • 總結(jié)開(kāi)發(fā)過(guò)程踩到的坑(三)

    摘要:本文章旨在總結(jié)開(kāi)發(fā)過(guò)程中碰到的容易忘記或者比較重要的坑,一方面加深自己對(duì)于該部分的理解,另一方面希望能夠分享給大家,知識(shí)在于分享,當(dāng)然踩過(guò)的坑也不例外滑稽。 在日常工作中,時(shí)常會(huì)碰到各種各樣的坑,有時(shí)真的覺(jué)得很多時(shí)候開(kāi)發(fā)的經(jīng)驗(yàn)都是踩坑踩出來(lái)的。在通往大牛的道路上,希望自己能夠跨越重重阻礙,越走越遠(yuǎn)。學(xué)會(huì)時(shí)??偨Y(jié),不斷提升自己。 本文章旨在總結(jié)開(kāi)發(fā)過(guò)程中碰到的容易忘記或者比較重要的坑,...

    April 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

amuqiao

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<