[英]Python Pointer Ambiguity
假設我有一個帶列表baz的函數foo,在foo中,我想像這樣清除baz:
baz = []
foo(baz)
foo(baz):
baz = []
現在,此代碼無法執行我想要的操作,因為它創建了一個稱為baz的新本地列表。 我知道還有其他方法可以執行此操作,但是我想知道Python解決了此類歧義,其中語句
baz = []
可以解釋為告訴Python將外部作用域baz變量指向一個新的空內存塊,或創建一個指向空內存塊的新指針。
編輯
請注意,我不是在問如何清除列表。 我在問Python解釋器的行為。 拒絕投票之前,請先清楚閱讀問題。
如果您使用global
或nonlocal
關鍵字明確地將變量賦值給Python,Python只會將其視為從外部作用域分配給變量。 global
表示全局變量, nonlocal
表示閉包變量的Python 3專有關鍵字:
x = 1
def change_x():
global x
x = 2
def dont_change_x():
# no global
x = 3
change_x()
print(x) # prints 2
dont_change_x()
print(x) # still prints 2
否則,它將始終將分配解釋為分配給局部變量。
如果您打算清除列表中的項目,則無需將當前名稱重新分配給新列表,只需通過切片將舊名稱清除:
foo(baz):
baz[:] = [] # clears out list baz
baz[:]
是索引列表中所有項目並為其分配新值的一種方法
更新 :
如果在分配給新列表的操作中使用了相同的名稱,則解釋器會將該名稱重新分配給新的list
對象:
>>> baz = []
>>> id(baz)
14832064
>>> baz = []
>>> id(baz)
14834304
除了使用切片來重構舊列表以外,名稱baz
將不再是對old
列表的引用。
看一下這篇文章,了解python 通過賦值傳遞參數的方式。
發生的事情是您將變量baz重新定義為另一個列表,因此它不再具有對外部baz的引用。 您需要直接操作列表中的元素。
例如,如果您要向baz添加元素,則外部列表將獲得更改:
def foo(baz):
baz.append('baz')
但是通過這樣做:
def foo(baz):
baz = []
您為baz分配了一個新列表,對外部baz的引用現在已斷開。
對於您的情況,您有2個選項可以清除列表:
del baz[:]
baz[:] = []
使用切片:
>>> def foo(baz):
... baz[:] = []
...
>>> baz = [1, 2]
>>> foo(baz)
>>> baz
[]
該my_list[:]
告訴Python來代替所有的元素my_list
與賦值語句的右側的內容,指的是同一my_list
對象。
如果要清除列表,請使用.clear()
而不是創建新列表:
def foo(baz):
baz.clear()
旁注:要訪問foo()
的外部baz
,可以使用global
關鍵字。 但是在那種情況下,不會有任何歧義,因為python會通過拋出SyntaxError迫使您重命名該參數。
def foo(baz2):
global baz
baz = []
請注意,不建議使用global
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.