<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 問題來源   最近看到了一個python程序題,就三行代碼,卻思考了很久才考慮明白,決定分享一下。 ~~~ def num(): return [lambda x:i*x for i in range(4)] print([m(2) for m in num()]) ~~~ 預計結果為:0, 2, 4, 6 實際輸出為:6, 6, 6, 6 ## 思路分析 其實把上面的代碼拆分一下,等價于下面的代碼 ~~~ def func(): fun_lambda_list = [] for i in range(4): def lamb(x): return x*i fun_lambda_list.append(lamb) return fun_lambda_list ~~~ 我們再把上面的代碼加兩行print輸出,讓結果看的更加明顯: PS:**locals()**?函數會以字典類型返回當前位置的全部局部變量。 ~~~ def func(): fun_lambda_list = [] for i in range(4): def lamb(x): print('Lambda函數中 i {} 命名空間為:{}:'.format(i, locals())) return x*i fun_lambda_list.append(lamb) print('外層函數 I 為:{} 命名空間為:{}'.format(i, locals())) return fun_lambda_list fl = func() fl[0](1) fl[1](1) fl[2](1) fl[3](1) ~~~ 我們會發現,打印的結果為: ~~~ 外層函數 I 為:0 命名空間為:{'lambda_': <function func.<locals>.lambda_ at 0x00000116B6837488>, 'fun_lambda_list': [<function func.<locals>.lambda_ at 0x00000116B6837488>], 'i': 0} 外層函數 I 為:1 命名空間為:{'lambda_': <function func.<locals>.lambda_ at 0x00000116B6837510>, 'fun_lambda_list': [<function func.<locals>.lambda_ at 0x00000116B6837488>, <function func.<locals>.lambda_ at 0x00000116B6837510>], 'i': 1} 外層函數 I 為:2 命名空間為:{'lambda_': <function func.<locals>.lambda_ at 0x00000116B6837598>, 'fun_lambda_list': [<function func.<locals>.lambda_ at 0x00000116B6837488>, <function func.<locals>.lambda_ at 0x00000116B6837510>, <function func.<locals>.lambda_ at 0x00000116B6837598>], 'i': 2} 外層函數 I 為:3 命名空間為:{'lambda_': <function func.<locals>.lambda_ at 0x00000116B6837620>, 'fun_lambda_list': [<function func.<locals>.lambda_ at 0x00000116B6837488>, <function func.<locals>.lambda_ at 0x00000116B6837510>, <function func.<locals>.lambda_ at 0x00000116B6837598>, <function func.<locals>.lambda_ at 0x00000116B6837620>], 'i': 3} Lambda函數中 i 3 命名空間為:{'x': 1, 'i': 3}: Lambda函數中 i 3 命名空間為:{'x': 1, 'i': 3}: Lambda函數中 i 3 命名空間為:{'x': 1, 'i': 3}: Lambda函數中 i 3 命名空間為:{'x': 1, 'i': 3}: ~~~   可以發現:四次循環中外層函數命名空間中的**?i?從****?0-->1-->2-->3?最后固定為****3**,而在此過程中內嵌函數lamb函數中因為沒有定義?i?所以只有lamb函數動態運行時,在自己命名空間中找不到?i?才去外層函數復制?i = 3?過來,結果就是所有lamb函數的?i?都為 3,導致得不到預計輸出結果:0,2,4,6 只能得到?6,6,6,6。 ## 解決辦法 變閉包作用域為局部作用域 ``` def func(): fun_lambda_list = [] for i in range(4): def lambda_(x,i=i): print('Lambda函數中 i {} 命名空間為:{}:'.format(i, locals())) return x*i fun_lambda_list.append(lambda_) print('外層函數 I 為:{} 命名空間為:{}'.format(i, locals())) return fun_lambda_list fl = func() fl[0](1) fl[1](1) fl[2](1) fl[3](1) ``` ``` 外層函數 I 為:0 命名空間為:{'lambda_': <function func.<locals>.lambda_ at 0x0000021F12227488>, 'i': 0, 'fun_lambda_list': [<function func.<locals>.lambda_ at 0x0000021F12227488>]} 外層函數 I 為:1 命名空間為:{'lambda_': <function func.<locals>.lambda_ at 0x0000021F12227510>, 'i': 1, 'fun_lambda_list': [<function func.<locals>.lambda_ at 0x0000021F12227488>, <function func.<locals>.lambda_ at 0x0000021F12227510>]} 外層函數 I 為:2 命名空間為:{'lambda_': <function func.<locals>.lambda_ at 0x0000021F12227598>, 'i': 2, 'fun_lambda_list': [<function func.<locals>.lambda_ at 0x0000021F12227488>, <function func.<locals>.lambda_ at 0x0000021F12227510>, <function func.<locals>.lambda_ at 0x0000021F12227598>]} 外層函數 I 為:3 命名空間為:{'lambda_': <function func.<locals>.lambda_ at 0x0000021F12227620>, 'i': 3, 'fun_lambda_list': [<function func.<locals>.lambda_ at 0x0000021F12227488>, <function func.<locals>.lambda_ at 0x0000021F12227510>, <function func.<locals>.lambda_ at 0x0000021F12227598>, <function func.<locals>.lambda_ at 0x0000021F12227620>]} Lambda函數中 i 0 命名空間為:{'i': 0, 'x': 1}: Lambda函數中 i 1 命名空間為:{'i': 1, 'x': 1}: Lambda函數中 i 2 命名空間為:{'i': 2, 'x': 1}: Lambda函數中 i 3 命名空間為:{'i': 3, 'x': 1}: 輸出結果 ```   所以,再回到最開始的那段代碼。`lambda x: x*i`?為內層(嵌)函數,他的命名空間中只有 {'x': 1} 沒有?i?,所以運行時會向外層函數(這兒是列表解析式函數 \[ \])的命名空間中請求?i 。而當列表解析式運行時,列表解析式命名空間中的?i?經過循環依次變化為?0-->1-->2-->3?最后固定為?3?,所以當?`lambda x: x*i`?內層函數運行時,去外層函數取?i?每次都只能取到 3。   將代碼改成下面這樣輸出就會變成0,2,4,6. ~~~ def num(): return [lambda x,i=i:i*x for i in range(4)] print([m(2) for m in num()]) ~~~ ## LEGB規則   只有函數、類、模塊會產生作用域,代碼塊不會產生作用域。作用域按照變量的定義位置可以劃分為4類: ~~~ Local(函數內部)局部作用域 Enclosing(嵌套函數的外層函數內部)嵌套作用域(閉包) Global(模塊全局)全局作用域 Built-in(內建)內建作用域 ~~~   python解釋器查找變量時,會按照順序依次查找**局部作用域--->嵌套作用域--->全局作用域--->內建作用域**,在任意一個作用域中找到變量則停止查找,所有作用域查找完成沒有找到對應的變量,則拋出 NameError: name 'xxxx' is not defined的異常。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看