के बाद क्यों नहीं बुलाया जाता है, मुझे इसके साथ शुरू करने दें Why does __init__ not get called if __new__ called with no args का दोहराव नहीं है। मैंने __new__
और __init__
के लिए कुछ नमूना कोड सावधानीपूर्वक बनाने की कोशिश की है जिसमें मुझे कोई स्पष्टीकरण नहीं मिल रहा है।__nit__ को __new__ SOMETIMES
बुनियादी मानकों:
- एक आधार वर्ग NotMine कहा जाता है के रूप में यह एक और पुस्तकालय से आता है (मैं अंत में खुलासा नहीं, यहां नहीं महत्वपूर्ण)
- कि वर्ग एक
__init__
विधि है बदले में कॉल एक_parse
विधि - मैं उपवर्गों में
_parse
विधि ओवरराइड करने के लिए की जरूरत है - जो उपवर्ग मैं बना रहा हूं मंगलाचरण तक ज्ञात नहीं है
- मुझे पता है कि कारखाने डिजाइन तरीके हैं लेकिन मैं उन्हें यहाँ का उपयोग नहीं कर सकते हैं (अधिक अंत में)
- मैं
super
से सावधान उपयोग समस्याओं से बचने के बनाने की कोशिश की है Python logging: Why is __init__ called twice? - में मैं जानता हूँ कि यह भी की तरह है ' 'एक AbstractBaseMehtod अवसर लेकिन वह
__new__
के बाद और क्यों कुछ नमूने नीचे काम नहीं करते मैं अन्य मामलों है कि काम करने के लिए बात करने के लिए सक्षम होने के लिए लग रहे हैं के हर विवरण के लिए मदद नहीं की
वैसे भी, __init__
बुलाया जाना चाहिए और स्पष्टीकरण से बाहर निकलें।
class NotMine(object):
def __init__(self, *args, **kwargs):
print "NotMine __init__"
self._parse()
def _parse(self):
print "NotMine _parse"
class ABC(NotMine):
def __new__(cls,name,*args, **kwargs):
print "-"*80
print "Entered through the front door ABC.__new__(%s,%s,*%s,**%s)"%(cls,name,args,kwargs)
if name == 'AA':
obj = super(NotMine,ABC).__new__(AA,*args,**kwargs)
print "Exiting door number 1 with an instance of: %s"%type(obj)
return obj
elif name == 'BB':
obj = super(NotMine,ABC).__new__(BB,*args,**kwargs)
print "Exiting door number 2 with an instance of: %s"%type(obj)
return obj
else:
obj = super(NotMine,ABC).__new__(cls,*args,**kwargs)
print "Exiting door number 3 with an instance of: %s"%type(obj)
return obj
class AA(ABC):
def _parse(self):
print "AA _parse"
class BB(ABC):
def __init__(self, *args, **kw):
print "BB_init:*%s, **%s"%(args,kw)
super(BB,self).__init__(self,*args,**kw)
def _parse(self):
print "BB _parse"
class CCC(AA):
def _parse(self):
print "CCCC _parse"
print("########### Starting with ABC always calls __init__ ############")
ABC("AA") # case 1
ABC("BB") # case 2
ABC("NOT_AA_OR_BB") # case 3
print("########### These also all call __init__ ############")
AA("AA") # case 4
BB("BB") # case 5
AA("NOT_AA_OR_BB") # case 6
BB("NOT_AA_OR_BB") # case 7
CCC("ANYTHING") # case 8
print("########### WHY DO THESE NOT CALL __init__ ############")
AA("BB") # case 9
BB("AA") # case 10
CCC("BB") # case 11
आप कोड निष्पादित हैं, तो आप देख सकते हैं कि __new__
की प्रत्येक कॉल यह घोषणा की "जो दरवाजा" इसके माध्यम से और किस प्रकार से बाहर निकलने के लिए है। मैं एक ही "प्रकार" ऑब्जेक्ट के साथ उसी "दरवाजे" से बाहर निकल सकता हूं और __init__
एक मामले में बुलाया गया है, न कि दूसरे। मैंने "कॉलिंग" वर्ग के एमआरओ को देखा है और यह कोई अंतर्दृष्टि प्रदान नहीं करता है क्योंकि मैं उस वर्ग (या सीसीसी में एक उप-वर्ग) का आह्वान कर सकता हूं और __init__
कहलाता है।
समाप्ति नोट्स: मैं उपयोग कर रहा हूँ NotMine
पुस्तकालय Genshi MarkupTemplate और एक फैक्टरी डिजाइन विधि का उपयोग नहीं करने के लिए कारण है उनके TemplateLoader एक defaultClass की जरूरत है कि निर्माण करने के लिए है। मैं तब तक नहीं जानता जब तक कि मैं पार्सिंग शुरू नहीं करता, जो मैं __new__
में करता हूं। वहां बहुत अच्छा वूडू जादू है जो गेन्सी लोडर और टेम्पलेट्स करते हैं जो इस प्रयास को लायक बनाते हैं।
मैं अपने लोडर का एक असम्बद्ध उदाहरण चला सकता हूं और वर्तमान में जब तक मैं केवल एबीसी (अमूर्त सॉर्ट-ऑफ-फैक्ट्री) कक्षा को डिफ़ॉल्ट रूप से पास नहीं करता तब तक सब कुछ काम करता है। चीजें अच्छी तरह से काम कर रही हैं लेकिन बाद में यह अस्पष्ट व्यवहार लगभग एक निश्चित बग है।
अद्यतन: इग्नेसियो,, शीर्ष पंक्ति सवाल किसी न किसी अगर लौटे वस्तु cls तो __init__
नहीं बुलाया जाता है एक "के कहने" नहीं है। मुझे लगता है कि "कन्स्ट्रक्टर" को कॉल करना (उदाहरण के लिए AA(args..)
गलत है क्योंकि यह __new__
को फिर से कॉल करेगा और आप ठीक कहां से शुरू कर चुके हैं। आप एक अलग पथ लेने के लिए एक तर्क संशोधित कर सकते हैं। इसका मतलब है कि आप ABC.__new__
को असीम रूप से दो बार कॉल करते हैं ।एक काम कर समाधान के रूप में ऊपर class ABC
संपादित करने के लिए है:
class ABC(NotMine):
def __new__(cls,name,*args, **kwargs):
print "-"*80
print "Entered through the front door ABC.__new__(%s,%s,*%s,**%s)"%(cls,name,args,kwargs)
if name == 'AA':
obj = super(NotMine,ABC).__new__(AA,*args,**kwargs)
print "Exiting door number 1 with an instance of: %s"%type(obj)
elif name == 'BB':
obj = super(NotMine,ABC).__new__(BB,*args,**kwargs)
print "Exiting door number 2 with an instance of: %s"%type(obj)
elif name == 'CCC':
obj = super(NotMine,ABC).__new__(CCC,*args,**kwargs)
print "Exiting door number 3 with an instance of: %s"%type(obj)
else:
obj = super(NotMine,ABC).__new__(cls,*args,**kwargs)
print "Exiting door number 4 with an instance of: %s"%type(obj)
## Addition to decide who calls __init__ ##
if isinstance(obj,cls):
print "this IS an instance of %s So call your own dam __init__"%cls
return obj
print "this is NOT an instance of %s So __new__ will call __init__ for you"%cls
obj.__init__(name,*args, **kwargs)
return obj
print("########### now, these DO CALL __init__ ############")
AA("BB") # case 9
BB("AA") # case 10
CCC("BB") # case 11
सूचना पिछले कुछ लाइनों। __init__
पर कॉल नहीं करना अगर यह एक "अलग" वर्ग मुझे समझ में नहीं आता है, विशेष रूप से जब "अलग" वर्ग __init__
पर कॉल करने वाले वर्ग का उप-वर्ग है। मुझे उपर्युक्त संपादन पसंद नहीं है लेकिन कम से कम मुझे नियम थोड़ा बेहतर मिलते हैं।
क्या गैन्शी मेटाक्लास का उपयोग कर रहा है? Http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python – Borealid
नहीं, मेरा नमूना कोड आधार के रूप में genshi का उपयोग नहीं करता है। –