2010-10-28 30 views
27

Sınıfın __init__ yönteminin argümanlarından biri için varsayılan değer olarak bir sınıf özniteliği kullanmak istiyorum. Bu yapı da, bir NameError durum oluşturur ve neden anlamıyorum:Örnek yöntem için sınıf değeri varsayılan değer olarak kullanabilir miyim?

class MyClass(): 
    __DefaultName = 'DefaultName' 
    def __init__(self, name = MyClass.__DefaultName): 
     self.name = name 

Bu neden başarısız etmez ve çalıştığını bunu yapmanın bir yolu var mı? documentation göre, çünkü bu

+0

emin olun [Ethan'ın cevabı] (http://stackoverflow.com/a/7697664/1709587) için daha az yararlı kabul edilen cevabı okumak için, bunu yapmanıza izin veren çalışma sözdizimi sağlar. –

cevap

22

: fonksiyon tanımlama yürütüldüğünde

varsayılan parametre değerleri değerlendirilir. Bu fonksiyon

__init__() tanımlanır

hala çözümlenen ediliyor olarak henüz MyClass.__DefaultName başvuruda bulunamaz böylece, MyClass tanımı, eksik tanımlandığında ifadesi, bir kez değerlendirilir demektir .

def __init__(self, name=None): 
    if name is None: 
     name = MyClass.__DefaultName 
    # ... 
+0

Sınıfa açıkça ismini vermemeyi tercih ederim. Sınıf ve sınıf özniteliklerine bir örnek yönteminden erişmek için önerilen bir yol ne olurdu? Tür (kendini) 'tamam mı? – Alexey

20

Python ile akılda tutulması gereken önemli bir nokta kodunun farklı bitleri ile birlikte yürütüldüğünde : yani geçici bir çözüm yollarından biri bu tür None gibi __init__() için özel benzersiz bir değer geçmektir Aslındave def ifadeleri göründüğünde, yalnızca daha sonra depolanmayacak şekilde yürütülür. Python local ad alanında ilk önce bulmaya çalışır MyClass.__DefaultName gördüğünde

def __init__(SELF, name = MyClass.__DefaultName): 

önce kodunuza böylece - bir def sayesinde yürütülmektedir tek şey () s arasında ne olursa olsun, çünkü anlamak biraz daha kolay Daha sonra modül (aka global) ad alanı ve son olarak builtins.

class ifadesini çalıştırırken local ad alanı nedir? Bu eğlenceli bölüm - class ad alanı olacak, ama şu anda anonim - bu yüzden adından (aka MyClass kodunuzda) başvuruda bulunamazsınız ama siz doğrudan herhangi bir şeye referans olabilir zaten tanımlanmış ... ve ne tanımlanmış? Sınıfınızda sadece bir şey var - __DefaultName. Yani __init__ bu gibi görünmelidir:

def __init__(SELF, name=__DefaultName): 

daha sonra MyClass._MyClass__DefaultName değiştirip bu değişiklikler yeni durumlarda ortaya olamaz unutmayın. Niye ya? __init__ def sadece bir kez çalıştırılır ve olduğundan ne olursa olsun değer __DefaultName uzağa saklanmış o anda vardı ve her zaman kullanılacaktır - Eğer yeni bir örneğini oluştururken doğrudan yeni bir değer belirtmedikçe:

my_instance = MyClass(name='new name') 
İlgili konular