亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Python > 正文

Python和Ruby中each循環引用變量問題(一個隱秘BUG?)

2020-02-23 05:26:38
字體:
來源:轉載
供稿:網友

雖然這個問題我是在 Python 里遇到的,但是用 Ruby 解釋起來比較容易一些。在 Ruby 里,遍歷一個數組可以有很多種方法,最常用的兩種無非是 for 和 each:
代碼如下:
arr = ['a', 'b', 'c']

arr.each { |e|
  puts e
}

for e in arr
  puts e
end
通常我比較喜歡后者,似乎因為寫起來比較好看,不過從效率上來說前者應該會稍微快一點,因為后者實際上是在遍歷的過程中對每個元素都調用一個 lambda 函數來做的,雖然一般情況下并不明顯,不過設置上下文并調用函數確實是有開銷的,特別是在動態語言里面(不考慮 JIT 內聯優化的話)。不過這次的問題并不是性能。然而確實跟“ each 對每個元素都會新建一個 scope 而 for 則不是”有關。

看下面一段代碼:
代碼如下:
arr = ['a', 'b', 'c']
h1 = Hash.new
h2 = Hash.new

arr.each { |e|
  h1[e] = lambda { e+'!'}
}

for e in arr
  h2[e] = lambda { e+'!' }
end

h1['a'].call # => ?
h2['a'].call # => ?
兩個 call 分別會得到什么?應該已經猜到了吧?分別是 'a!' 和 'c!' ,后者之所以是 'c!' 是因為 for 并沒有在循環的每一步都重新創建一個 scope ,因此三個 lambda 的 closure 引用到了同一個變量,而這個變量在最后一次被賦值為 'c' ,所以導致了這樣的后果。

問題其實出自我在用 Python 寫的一個小程序中的一段,代碼類似于這樣:
代碼如下:
for prop in public_props:
    setattr(proxy, 'get_%s'%prop, lambda: self.get_prop(prop))
其中 proxy 是我提供的一個代理對象,將 self 的一些公開的屬性給暴露出去,因為要限制對非 public 的屬性的訪問,我并不想在這個 proxy 中存放任何到 self 的引用,否則在沒有訪問權限限制的 Python 里通過類似 proxy._orig_self.some_private_prop 的方式來訪問是輕而易舉的。所以最后選擇了上面那樣的做法。

不幸的是,由于像剛才所說的那樣,for 并沒有每次都單獨創建 scope ,因此 closure 全部引用到了同一個變量上,導致所有的屬性值取出來都是最后一個屬性了??吹竭@樣詭異的 bug ,如果是在 C/C++ 里面,我肯定要懷疑是內存或者指針的問題了。不過想了半天才終于恍然大悟!不過 Python 里面沒有 Ruby 那么方便的 each 可以用,lambda 用起來也很雞肋,所以最后通過定義一個局部的函數來解決了:
代碼如下:
def proxy_prop(name):
    setattr(proxy, 'get_%s'%prop, lambda: self.get_prop(name)
for prop in public_props:
    proxy_prop(prop)
最后,還要多嘴一句,對于之前 Ruby 那個例子,如果把 each 和 for 的執行順序顛倒過來,會得到不同的結果:

代碼如下:arr = ['a', 'b', 'c']
h1 = Hash.new
h2 = Hash.new

for e in arr

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩在线观看av| 欧美电影免费在线观看| 国产999精品久久久影片官网| 最近中文字幕日韩精品| 97avcom| 国产精品直播网红| 欧美猛交ⅹxxx乱大交视频| 亚洲国产三级网| 国产精品国产自产拍高清av水多| 国产精品视频播放| 中文字幕在线成人| 欧美精品九九久久| 美女性感视频久久久| 成人福利视频在线观看| 亚洲国产成人爱av在线播放| 性欧美办公室18xxxxhd| 欧美福利视频在线| 国产福利成人在线| 欧美乱大交xxxxx| 中文字幕亚洲图片| 欧美亚洲视频在线看网址| 欧美亚洲第一页| 青青青国产精品一区二区| 亚洲色图狂野欧美| 欧美国产日韩一区二区三区| 91久久精品国产91性色| 色综久久综合桃花网| 亚洲国产精久久久久久久| 国产手机视频精品| 欧美午夜精品在线| 插插插亚洲综合网| 国产精品视频久久| 亚洲第一天堂无码专区| 九九久久久久99精品| 亚洲精品免费在线视频| 欧美肥老太性生活视频| 久久久久久久久久婷婷| 欧美一级电影在线| 亚洲欧洲日本专区| 亚洲一区二区三区四区视频| 亚洲三级av在线| 日韩精品极品视频免费观看| 久久久久久尹人网香蕉| 久久视频在线视频| 91网站免费观看| 精品成人av一区| 欧美一级电影久久| 中文字幕亚洲欧美在线| 68精品久久久久久欧美| 91理论片午午论夜理片久久| 色婷婷av一区二区三区在线观看| 91视频国产精品| 国产成人欧美在线观看| 国产成人精品电影久久久| 国产这里只有精品| 久久99青青精品免费观看| 国产精品免费久久久久久| 色妞在线综合亚洲欧美| 中文字幕久久精品| 亚洲高清福利视频| 97人人爽人人喊人人模波多| 91视频8mav| 亚洲成年人在线| 日韩激情视频在线| 91精品国产精品| 亚洲综合精品伊人久久| 亚洲国产精品人人爽夜夜爽| 亚洲天堂免费在线| 久久天堂av综合合色| 色综合伊人色综合网| 亚洲护士老师的毛茸茸最新章节| 国产一区二区三区精品久久久| 亚洲精品99久久久久| 日本一区二区三区在线播放| 91久热免费在线视频| 久久久久久久久久久av| 在线免费看av不卡| 91色精品视频在线| 亚洲人成在线免费观看| 在线播放国产一区中文字幕剧情欧美| 日韩高清不卡av| 国产成人aa精品一区在线播放| 国产在线观看精品| 欧洲精品毛片网站| 欧美视频一区二区三区…| 精品欧美国产一区二区三区| 97超级碰碰碰久久久| 久久99精品久久久久久噜噜| 麻豆国产va免费精品高清在线| 成人妇女免费播放久久久| 国产一区二区在线播放| 2018日韩中文字幕| 91亚洲国产成人精品性色| 日本久久亚洲电影| 5566日本婷婷色中文字幕97| 这里只有精品视频| 欧美在线观看一区二区三区| 最近2019中文免费高清视频观看www99| 欧美在线观看视频| 欧美精品videos另类日本| 欧美性猛交丰臀xxxxx网站| 精品中文字幕久久久久久| 97精品国产91久久久久久| 欧美成aaa人片在线观看蜜臀| 欧美区在线播放| 国产91精品青草社区| 欧美大尺度电影在线观看| 一区二区三区www| 北条麻妃久久精品| 欧美成人午夜激情| 91最新在线免费观看| 国产98色在线| 精品福利在线视频| 久久综合国产精品台湾中文娱乐网| 911国产网站尤物在线观看| 亚洲最大av网站| 欧美一区二区大胆人体摄影专业网站| 亚洲色图偷窥自拍| 影音先锋日韩有码| 亚洲精品一区在线观看香蕉| 超碰精品一区二区三区乱码| 92版电视剧仙鹤神针在线观看| 性欧美办公室18xxxxhd| 久久久噜噜噜久噜久久| 亚洲人线精品午夜| 国产精品久久久久久久久影视| 欧美丝袜第一区| 欧美国产日韩一区二区三区| 久久久久免费精品国产| 久国内精品在线| 日韩美女视频中文字幕| 欧美在线精品免播放器视频| 北条麻妃一区二区在线观看| 91香蕉嫩草影院入口| www亚洲精品| 在线观看国产精品91| 91系列在线播放| 亚洲美女av网站| 亚洲欧洲在线观看| 精品国产网站地址| 亚洲第一在线视频| 亚洲美女性生活视频| 日韩专区在线播放| 国产精品三级美女白浆呻吟| 日韩av一区在线观看| 欧美另类99xxxxx| 欧美日韩亚洲激情| 国产欧美中文字幕| 日韩国产精品亚洲а∨天堂免| 91在线直播亚洲| 欧美精品一本久久男人的天堂| 欧美性xxxxxx| 国产成人精品久久亚洲高清不卡| 播播国产欧美激情| 日韩精品免费在线播放| 久久夜色精品亚洲噜噜国产mv| 97精品国产97久久久久久春色| 亚洲女成人图区| 成人黄色在线观看| 久久好看免费视频| 国产精品美女免费| 91久久精品久久国产性色也91| 欧美成人h版在线观看| 国产精品com|