2010-06-20 59 views
1
class x: 
    def __init__(self): 
     self.y=None 
     self.sillyFunc(self.y) 
    def sillyFunc(self,argument): 
     if argument is None: 
      argument='my_name_as_argument' 
     self.printy() 
    def printy(self): 
     print self.y 

根據我上面的代碼應打印> my_name_as_argument,我哪裏錯了?python不使用複製引用?爲什麼下面的代碼不工作呢?

+0

Python使用call-by-sharing,它從不*改變引用指向的內容。這使得可變對象和不可變對象看起來被區別對待,儘管它們確實不是。在你的情況下,你只是將'my_name_as_argument'賦值給局部變量'argument' - 你永遠不會做任何會改變'self.y'的值。 – 2010-06-20 18:06:07

回答

4

在Python中,一切都是對象,變量包含對對象的引用。當你進行函數調用時,它使拷貝的引用。包括Guido van Rossum在內的一些人稱此爲「按對象引用調用」。 Important note來自Wikipedia:

函數不能在其調用函數中更改變量引用的值。

您發佈的代碼不會打印任何內容。我想你的意思是這個額外的行添加到您的程序:

x() 

這就導致輸出:None。這並不令人意外,因爲您正在打印self.y的值,但您曾分配給self.y的唯一值是None

在Python中,字符串是不可變的。重新分配argument的值只覆蓋參考的本地副本。它不會修改原始字符串。

正如您在評論中提出的那樣,如果您使用可變對象並重新分配引用,那麼這又不會做你想做的事 - 原始對象不受影響。如果你想改變一個可變對象,你可以調用一個改變它的方法。簡單地重新分配引用不會更改原始對象。

如果你想self.y指向一個新的對象,那麼你必須直接指定對象引用self.y

+0

讓我說我不使用字符串,而是我分配一些對象參數作爲參數= Some_class()即使然後它不工作 – 2010-06-20 14:25:07

+0

這種機制通常被稱爲「通過引用複製」,AFAIR即使在一些教科書(但我可以現在不提供參考)。 – 2010-06-20 14:35:55

+0

@Konrad:有趣。我已更新我的帖子,以使第一段更清晰。 – 2010-06-20 14:41:06

5

的分配新建分配FY

argument='my_name_as_argument' 

隻影響局部變量argument。它不會更改self.y指向的內容。

1

它取決於您是否更改引用對象本身(如果此對象是可變的)或將引用替換爲另一個對象。看到下面的例子,它使用了一個可變列表...

>>> def test(arg): 
...  arg.append(123) 
...  
... 
>>> s = [] 
>>> print s 
[] 
>>> test(s) 
>>> print s 
[123]