簡體   English   中英

Python指針歧義

[英]Python Pointer Ambiguity

假設我有一個帶列表baz的函數foo,在foo中,我想像這樣清除baz:

baz = []
foo(baz)

foo(baz):
    baz = []

現在,此代碼無法執行我想要的操作,因為它創建了一個稱為baz的新本地列表。 我知道還有其他方法可以執行此操作,但是我想知道Python解決了此類歧義,其中語句

 baz = []

可以解釋為告訴Python將外部作用域baz變量指向一個新的空內存塊,或創建一個指向空內存塊的新指針。

編輯

請注意,我不是在問如何清除列表。 我在問Python解釋器的行為。 拒絕投票之前,請先清楚閱讀問題。

如果您使用globalnonlocal關鍵字明確地將變量賦值給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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM