2010-10-28 13 views
27

मैं अपनी कक्षा के __init__ विधि के तर्कों में से किसी एक के लिए डिफ़ॉल्ट मान के रूप में क्लास विशेषता का उपयोग करना चाहता हूं। यह निर्माण एक NameError अपवाद है, हालांकि जन्म देती है, और मुझे समझ नहीं आता क्यों:क्या मैं एक आवृत्ति विधि के लिए डिफ़ॉल्ट मान के रूप में कक्षा विशेषता का उपयोग कर सकता हूं?

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

क्यों असफल होता है, और वहाँ यह है कि काम करता है करने के लिए एक तरीका है?

+0

सुनिश्चित करें [एथन के उत्तर] (http://stackoverflow.com/a/7697664/1709587) के कम सहायक स्वीकृत उत्तर को पढ़ने के लिए, जो कामकाजी वाक्यविन्यास प्रदान करता है जो आपको ऐसा करने देता है। –

उत्तर

22

वजह यही है, documentation के अनुसार: जब समारोह परिभाषा निष्पादित किया जाता है

डिफ़ॉल्ट पैरामीटर मान मूल्यांकन किया जाता है। इसका मतलब है कि अभिव्यक्ति एक बार जब समारोह

जब __init__() परिभाषित किया गया है, MyClass की परिभाषा, के रूप में यह अभी भी पार्स किया जा रहा है, अधूरा है ताकि आप MyClass.__DefaultName के लिए अभी तक का उल्लेख नहीं कर सकते हैं परिभाषित किया गया है मूल्यांकन किया जाता है, ।

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

मैं स्पष्ट रूप से नाम से कक्षा का उल्लेख नहीं करना चाहूंगा। एक उदाहरण विधि से वर्ग और वर्ग विशेषताओं तक पहुंचने का एक अनुशंसित तरीका क्या होगा? क्या 'टाइप (स्वयं)' ठीक है? – Alexey

20

अजगर के साथ ध्यान में रखने की एक महत्वपूर्ण बात है जब कोड की विभिन्न बिट्स के साथ क्रियान्वित कर रहे हैं के साथ,: एक ही रास्ता है कि आस-पास काम करने के लिए, __init__() के लिए एक विशेष अनूठा मूल्य पारित करने के लिए इस तरह के None के रूप में है तथ्य यह है कि class और def कथन निष्पादित किए जाते हैं जब देखा जाता है, न केवल बाद में संग्रहीत किया जाता है। जब अजगर MyClass.__DefaultName यह local नाम स्थान में पहली यह खोजने की कोशिश करता देखता है ऊपर

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

अपने कोड में इतना - एक def के साथ यह समझने के लिए, क्योंकि केवल एक चीज है निष्पादित किया जा रहा है जो कुछ भी () रों के बीच है थोड़ा आसान है , फिर मॉड्यूल (उर्फ global) नामस्थान, और अंत में builtins में।

class कथन निष्पादित करते समय local नामस्थान क्या है? यह मजेदार हिस्सा है - यह class नेमस्पेस बन जाएगा, लेकिन फिलहाल यह अनाम है - इसलिए आप इसे नाम से संदर्भित नहीं कर सकते हैं (उर्फ MyClass अपने कोड में) लेकिन आप सीधे किसी भी संदर्भ का संदर्भ दे सकते हैं पहले ही परिभाषित किया गया है ... और क्या परिभाषित किया गया है? आपके वर्ग उदाहरण में केवल एक चीज - __DefaultName। तो अपने __init__ इस तरह दिखना चाहिए:

def __init__(SELF, name=__DefaultName): 

ध्यान रखें कि आप MyClass._MyClass__DefaultName बाद में नहीं बदल सकते हैं और उन परिवर्तनों को नई उदाहरणों में दिखा। क्यूं कर? क्योंकि __init__ डीईएफ़ केवल एक बार निष्पादित किया जाता है, और जो मूल्य __DefaultName उस पल में था दूर रख ली गई है और हमेशा उपयोग किया जाएगा - जब तक आप सीधे एक नया मान जब आप एक नया उदाहरण बनाने निर्दिष्ट करें:

my_instance = MyClass(name='new name') 
संबंधित मुद्दे

 संबंधित मुद्दे