मान लीजिए मेरा मॉड्यूल myclass.py
है, और यहां कोड है:
#!/usr/bin/env python
# coding=utf-8
class A(object):
b = B()
def __init__(self):
pass
class B(object):
pass
और इसे आयात करें
In [1]: import myclass
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-1-e891426834ac> in <module>()
----> 1 import myclass
/home/python/myclass.py in <module>()
2 # coding=utf-8
3
----> 4 class A(object):
5 b = B()
6 def __init__(self):
/home/python/myclass.py in A()
3
4 class A(object):
----> 5 b = B()
6 def __init__(self):
7 pass
NameError: name 'B' is not defined
मुझे पता है कि अगर मैं कक्षा ए के ऊपर कक्षा बी को परिभाषित करता हूं, तो ठीक है, कोई त्रुटि नहीं है। लेकिन, मैं ऐसा नहीं करना चाहता, क्या इसे हल करने के लिए कोई अन्य तरीके हैं। और मुझे पता है कि सी में फंक्शन डिक्लेरेशन होता है।धन्यवाद!
3 जवाब
वर्ग परिभाषा एक बयान है। जब कथन AA
निष्पादित किया जाता है, BB
का कथन अभी तक निष्पादित नहीं होता है। इसलिए, अभी तक कोई वर्ग B
नहीं है और आपको NameError: name 'B' is not defined
मिलता है
class A(object):
b = B() # <== AA
def __init__(self):
pass
class B(object): # <== BB
pass
ठीक करना:
आप कक्षाओं का क्रम बदल सकते हैं:
class B(object):
pass
class A(object):
b = B()
def __init__(self):
pass
आप B
वर्ग का उपयोग करने वाले कथन को classmethod
में स्थानांतरित कर सकते हैं और इसे कक्षा B
की परिभाषा के बाद कॉल कर सकते हैं:
class A(object):
@classmethod
def init(cls):
cls.b = B()
def __init__(self):
pass
class B(object):
pass
A.init()
यदि आप इसे ऐसा करते हैं तो इसे काम करना चाहिए:
class A(object):
def __init__(self):
self.b = B()
class B(object):
pass
संपादित करें: आप इसे इस तरह कर सकते हैं यदि आप कक्षा ए लिखने के बाद कक्षा की सभी परिभाषाएं लिखना चाहते हैं।
class B:
pass
class A(object):
b = B()
def __init__(self):
pass
class B(object):
def __init__(self):
pass
संपादित करें 2: उपरोक्त समाधान पर ध्यान न दें, यह काम नहीं करता है।
क्या आप जो कर रहे हैं उसे करने का कोई अच्छा कारण है? सामान्य तौर पर यह पायथन में काफी खतरनाक पैटर्न है।
आपके मामले में
class A(object):
b = B()
def __init__(self):
pass
आप कक्षा ए के लिए बी का एक उदाहरण बाध्य कर रहे हैं, जिसका अर्थ है कि कक्षा ए का प्रत्येक उदाहरण कक्षा बी के समान उदाहरण को साझा करेगा। यह एक ऐसा मामला है जिसे आपको ठीक से संभालना होगा।
आम तौर पर आप यह नहीं चाहते हैं, यदि आप चाहते हैं कि ए का प्रत्येक उदाहरण बी के उदाहरण से संबंधित हो, तो आपको __init__
के अंदर असाइनमेंट करना होगा।
class A(object):
def __init__(self):
self.b = B()
इन मामलों में यह मीटर नहीं है जहां कक्षा बी परिभाषित की गई है, क्योंकि यह रन टाइम पर तत्काल है।
फिर से सावधान रहें कि दो मामलों में शब्दार्थ बहुत अलग है (यदि आप जावा को जानते हैं, तो पूर्व एक static
विशेषता को परिभाषित करने जैसा है)।
के बारे में:
और मुझे पता है कि सी में, समारोह घोषणा है
आपको सी जैसी भाषा के साथ बहुत अधिक समानताएं नहीं बनानी चाहिए, जो कई पहलुओं पर बहुत अलग है, सबसे महत्वपूर्ण: यह एक संकलित भाषा है, इसका मतलब है कि अनुवाद होने से पहले आपके कोड को पूरी तरह से पार्स किया गया है। मशीनी भाषा के लिए, इसलिए आप कार्य घोषणा कर सकते हैं और अपने नामस्थान को पॉप्युलेट कर सकते हैं, भले ही आप चीजों को परिभाषित करते हों।
पायथन एक व्याख्या की गई भाषा है, जिसका मूल रूप से अर्थ यह है कि प्रत्येक कथन अनुवादित है जब इसे कहा जाता है और जब मॉड्यूल आयात किया जाता है तो कक्षा घोषणा को कॉल किया जाता है।
तो संक्षेप में: यदि आपको वास्तव में कक्षा बाध्य उदाहरण की आवश्यकता है, तो आपको कक्षा ए से पहले कक्षा बी घोषित करना होगा, अन्यथा आपको __init__
के अंदर बी को तत्काल करना होगा, फिर आप जहां चाहें बी घोषित कर सकते हैं (चूंकि इसे रनटाइम पर कहा जाता है)।
संबंधित सवाल
नए सवाल
python
पायथन एक बहु-प्रतिमान है, गतिशील रूप से टाइप किया हुआ, बहुउद्देशीय प्रोग्रामिंग भाषा है। यह एक साफ और एक समान वाक्यविन्यास सीखने, समझने और उपयोग करने के लिए त्वरित होने के लिए डिज़ाइन किया गया है। कृपया ध्यान दें कि अजगर 2 आधिकारिक तौर पर 01-01-2020 के समर्थन से बाहर है। फिर भी, संस्करण-विशिष्ट पायथन सवालों के लिए, [अजगर -२.०] या [अजगर -३.x] टैग जोड़ें। पायथन वेरिएंट (जैसे, ज्योथन, PyPy) या लाइब्रेरी (उदा।, पांडस और न्यूमपी) का उपयोग करते समय, कृपया इसे टैग में शामिल करें।