2011-01-30 23 views
73

Bir şekilde, aşağıdaki Düğüm sınıfında, wordList ve adjacencyList değişkeni, tüm Düğüm örnekleri arasında paylaşılır.Python yapıcısı ve varsayılan değeri

>>> class Node: 
...  def __init__(self, wordList = [], adjacencyList = []): 
...   self.wordList = wordList 
...   self.adjacencyList = adjacencyList 
... 
>>> a = Node() 
>>> b = Node() 
>>> a.wordList.append("hahaha") 
>>> b.wordList 
['hahaha'] 
>>> b.adjacencyList.append("hoho") 
>>> a.adjacencyList 
['hoho'] 

Ben yapıcı parametreleri için varsayılan değer (bu durumda boş liste) kullanmaya devam edebilir ancak kendi wordlist ve adjacencyList değişkenleri olması a ve b hem almak için herhangi bir yolu var mı?

Python 3.1.2 kullanıyorum.

+1

olası yinelenen http://stackoverflow.com/questions/2681243/how-should-i-declare-default-values-for- örnek-değişkenler-python) –

+0

Python'da ["En Az Şaşkınlık" ın olası yinelenmesi: Hangi kapsamdaki Değişken Varsayılan Değişkeni nedir?] (http://stackoverflow.com/questions/1132941/least-astonishment-in-python -bu-kapsam-is-the-mutable-varsayılan-argüman-in) basitlik için –

cevap

91

Değiştirilebilir varsayılan değişkenler genellikle istediğiniz şeyi yapmaz. Bunun yerine, bu deneyin:

class Node: 
    def __init__(self, wordList=None, adjacencyList=None): 
     if wordList is None: 
      self.wordList = [] 
     else: 
      self.wordList = wordList 
     if adjacencyList is None: 
      self.adjacencyList = [] 
     else: 
      self.adjacencyList = adjacencyList 
+20

Bunlar da tek-liner olabilir: wordList değilse başka bir deyişle, self.wordList = wordList Yok [] ', veya biraz daha az güvenli, 'self.wordList = wordList veya []'. –

+1

Bu Pythonic yol olarak kabul edilir, ama ben "özel durumlar yeterince özel değildir" çünkü krousey'in yolunu tercih ederim. –

+0

@JoshBleecherSnyder Parmağımı üzerine koyamıyorum, ikincisini eskiden daha az güvenli yapan nedir? – markdsievers

15

Ben denemek:

self.wordList = list(wordList) 

yerine aynı nesneye başvuran bir kopyasını yapmak için zorlamak.

+1

+1 – Hery

23

burada neler olduğunu açıklayalım:

Python 3.1.2 (r312:79147, Sep 27 2010, 09:45:41) 
[GCC 4.4.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> class Foo: 
...  def __init__(self, x=[]): 
...   x.append(1) 
... 
>>> Foo.__init__.__defaults__ 
([],) 
>>> f = Foo() 
>>> Foo.__init__.__defaults__ 
([1],) 
>>> f2 = Foo() 
>>> Foo.__init__.__defaults__ 
([1, 1],) 

varsayılan argümanlar söz konusu fonksiyonun bir niteliktir bir demet içinde saklanır olduğunu görebilirsiniz. Bu aslında söz konusu sınıfla ilgisi yoktur ve herhangi bir işlev için gider. Python 2'de, özellik func.func_defaults olacaktır.

Diğer posterler de işaret ettiğinden, büyük olasılıkla None'u bir sentinel değeri olarak kullanmak ve her örneğe kendi listesi vermek istersiniz.

11
class Node: 
    def __init__(self, wordList=None adjacencyList=None): 
     self.wordList = wordList or [] 
     self.adjacencyList = adjacencyList or [] 
[Python içinde örnek değişkenleri için varsayılan değerleri beyan etmelidir nasıl?] (Içinde
İlgili konular