@ codelogic उत्तम जवाब की व्याख्या करने के लिए सबसे सटीक उत्तर हो सकता है, मैं एक और अधिक स्पष्ट दृष्टिकोण का प्रस्ताव।यह वही तकनीक है जो .
ऑपरेटर एक क्लास विधि को बाध्य करने के लिए पूरी तरह से चला जाता है जब आप इसे आवृत्ति विशेषता के रूप में एक्सेस करते हैं, सिवाय इसके कि आपकी विधि वास्तव में कक्षा के बाहर परिभाषित एक फ़ंक्शन होगी।
@ कोडेलोगिक कोड के साथ काम करना, केवल अंतर यह है कि विधि कैसे बाध्य है। मैं इस तथ्य का उपयोग कर रहा हूं कि पाइथन में कार्य और विधियां गैर-डेटा descriptors हैं, और __get__
विधि का आह्वान कर रही हैं। विशेष रूप से ध्यान दें कि मूल और प्रतिस्थापन दोनों के समान हस्ताक्षर होते हैं, जिसका अर्थ है कि आप प्रतिस्थापन को पूर्ण श्रेणी विधि के रूप में लिख सकते हैं, self
के माध्यम से सभी इंस्टेंस विशेषताओं तक पहुंच सकते हैं।
class Dog:
def bark(self):
print "Woof"
def new_bark(self):
print "Woof Woof"
foo = Dog()
# "Woof"
foo.bark()
# replace bark with new_bark for this object only
foo.bark = new_bark.__get__(foo, Dog)
foo.bark()
# "Woof Woof"
एक उदाहरण विशेषता के लिए बाध्य विधि बताए करके, आप एक विधि अधिभावी के एक लगभग पूरा अनुकरण बनाया है। गायब होने वाली एक आसान सुविधा super
के नो-एर्ग संस्करण तक पहुंच है, क्योंकि आप कक्षा परिभाषा में नहीं हैं। एक और बात यह है कि __name__
आपकी बाध्य विधि की विशेषता उस कार्य का नाम नहीं लेगी जो इसे ओवरराइड कर रही है, क्योंकि यह कक्षा परिभाषा में होगी, लेकिन आप इसे मैन्युअल रूप से सेट कर सकते हैं। तीसरा अंतर यह है कि आपकी मैन्युअल रूप से बाध्य विधि एक सादा विशेषता संदर्भ है जो केवल एक कार्य होता है। .
ऑपरेटर कुछ भी नहीं करता है लेकिन उस संदर्भ को प्राप्त करता है। दूसरी ओर एक उदाहरण से एक नियमित विधि का आह्वान करते समय, बाध्यकारी प्रक्रिया हर बार एक नई बाध्य विधि बनाता है।
एकमात्र कारण यह है कि यह काम करता है, वैसे ही, उदाहरण विशेषताएँ गैर-डेटा वर्णनकर्ताओं को ओवरराइड करती हैं। डेटा डिस्क्रिप्टर के पास __set__
विधियां हैं, जो विधियां (सौभाग्य से आपके लिए) नहीं हैं। वर्ग में डेटा डिस्क्रिप्टर वास्तव में किसी भी आवृत्ति विशेषताओं पर प्राथमिकता लेते हैं। यही कारण है कि आप किसी संपत्ति को असाइन कर सकते हैं: जब आप असाइनमेंट करने का प्रयास करते हैं तो उनकी __set__
विधि लागू होती है। मैं व्यक्तिगत रूप से इसे एक कदम आगे ले जाना चाहता हूं और उदाहरण के __dict__
में अंतर्निहित विशेषता के वास्तविक मूल्य को छिपाना पसंद करता हूं, जहां यह सामान्य माध्यमों से अप्राप्य है क्योंकि संपत्ति इसे छाया देती है।
आपको यह भी ध्यान में रखना चाहिए कि यह magic (double underscore) methods के लिए व्यर्थ है। जादू तरीकों को निश्चित रूप से इस तरह से ओवरराइड किया जा सकता है, लेकिन उनके द्वारा उपयोग किए जाने वाले संचालन केवल प्रकार को देखते हैं। उदाहरण के लिए, आप अपने उदाहरण में कुछ खास करने के लिए __contains__
सेट कर सकते हैं, लेकिन x in instance
पर कॉल करना उस पर ध्यान देगा और इसके बजाय type(instance).__contains__(instance, x)
का उपयोग करेगा। यह पाइथन data model में निर्दिष्ट सभी जादू विधियों पर लागू होता है।
स्रोत
2017-10-15 16:12:22
@arivero: मैंने सोचा था कि "कृपया इसे दिखाए गए अनुसार नहीं करें" जो पूरी तरह स्पष्ट है। आप यह और अधिक स्पष्ट करने के लिए क्या अन्य या अलग शब्द देखना चाहते हैं कि यह उस प्रश्न का उत्तर नहीं दे रहा है, लेकिन यह सलाह दे रहा है कि यह एक बुरा विचार क्यों है? –
मैं सलाह में असहमत नहीं हूं, न ही ओपी जैसा लगता है। लेकिन मुझे लगता है कि लोगों से पूछने के कारण हैं। या यहां तक कि अगर ओपी नहीं है, तो अन्य भविष्य के आगंतुक भी कर सकते हैं। तो, आईएमएचओ, एक उत्तर और एक झगड़ा बेहतर है कि सिर्फ एक झगड़ा। – arivero
@arivero: उसने मेरे प्रश्न का उत्तर नहीं दिया। –