2010-02-04 4 views
9

पायथन में किसी अन्य, तृतीय-पक्ष मॉड्यूल से क्लास विधि को फिर से परिभाषित करना कितना बुरा है?किसी तृतीय-पक्ष मॉड्यूल से किसी विधि को ओवरराइड करना कितना बुरा है?

वास्तव में, उपयोगकर्ता न्यूमपी मैट्रिस बना सकते हैं जिनमें numbers with uncertainty शामिल है; आदर्श रूप में, मैं उनके कोड को अनमोडिफाइड चलाने के लिए चाहूंगा (जब कोड फ़्लोट मैट्रिस का उपयोग करता है); विशेष रूप से, यह बहुत अच्छा होगा अगर मैट्रिक्स m के विपरीत m.I के साथ प्राप्त किया जा सकता है, इस तथ्य के बावजूद कि m.I को अपने कोड के साथ गणना की जानी है (मूल I विधि सामान्य रूप से काम नहीं करती है)।

numpy.matrix.I को फिर से परिभाषित करना कितना बुरा है? एक बात के लिए, यह तीसरे पक्ष के कोड के साथ छेड़छाड़ करता है, जिसे मैं पसंद नहीं करता, क्योंकि यह मजबूत नहीं हो सकता है (क्या होगा अगर अन्य मॉड्यूल समान हों? ...)। एक और समस्या यह है कि नया numpy.matrix.I एक रैपर है जिसमें एक छोटा ओवरहेड शामिल होता है जब मूल numpy.matrix.I वास्तव में व्यस्त मैट्रिक्स प्राप्त करने के लिए लागू किया जा सकता है।

NumPy matrices subclassing है और केवल I विधि को बेहतर ढंग से बदल रहा है? इससे उपयोगकर्ता अपने कोड को अपडेट कर सकते हैं और m = matrix_with_uncert(…) (numpy.matrix(…) का उपयोग करते हुए अनिश्चितता के साथ संख्याओं के मैट्रिक्स बना सकते हैं, फ्लोट्स के मैट्रिक्स के लिए), लेकिन शायद यह एक असुविधा है जिसे मजबूती के लिए स्वीकार किया जाना चाहिए? मैट्रिक्स इनवर्जन अभी भी m.I के साथ किया जा सकता है, जो अच्छा है ... दूसरी तरफ, यह अच्छा होगा अगर उपयोगकर्ता डेटा प्रकारों की जांच को परेशान किए बिना सीधे numpy.matrix() के साथ अपने सभी मैट्रिस (फ्लोट या अनिश्चितताओं के साथ संख्याओं) का निर्माण कर सकें ।

कोई टिप्पणी, या अतिरिक्त दृष्टिकोण का स्वागत किया जाएगा!

उत्तर

11

सबक्लासिंग (जिसमें आमतौर पर शब्द का उपयोग किया जाता है, ओवरराइडिंग शामिल है) आम तौर पर उपलब्ध होने पर भी "बंदर-पैचिंग" (मौजूदा कक्षाओं या मॉड्यूल में परिवर्तित विधियों को भरना) के लिए बहुत बेहतर है (अंतर्निर्मित प्रकार , जिसका मतलब सी में लागू किया गया है, बंदर-पैचिंग के खिलाफ खुद को बचा सकता है, और उनमें से अधिकांश करते हैं)।

उदाहरण के लिए, यदि आपकी कार्यक्षमता बंदर-पैचिंग पर निर्भर करती है, तो यह किसी भी समय कक्षा में लागू होने के लिए अपग्रेड हो जाने पर कक्षा को अपग्रेड कर दिया जाएगा (गति के लिए या विशेष रूप से बंदर पैचिंग के खिलाफ बचाव के लिए)। तीसरे पक्ष के पैकेज के रखरखाव बंदर-पैचिंग से नफरत करते हैं क्योंकि इसका मतलब है कि उन्हें बेकार उपयोगकर्ताओं से फर्जी बग रिपोर्ट मिलती हैं, जो (उनसे अनजान) वास्तव में एक छोटी गाड़ी बंदर-पैच का उपयोग कर रही हैं जो तीसरे पक्ष के पैकेज को तोड़ती है, जहां उत्तरार्द्ध (जब तक टूटा बंदर- बुद्धिमान) निर्दोष है। आपने पहले से ही संभावित प्रदर्शन हिट पर टिप्पणी की है।

संकल्पनात्मक रूप से, "अनिश्चितता वाले संख्याओं का मैट्रिक्स" "संख्याओं के मैट्रिक्स" से एक अलग अवधारणा है। सबक्लासिंग यह स्पष्ट रूप से व्यक्त करता है, बंदर-पैचिंग इसे छिपाने की कोशिश करता है। यह वास्तव में बंदर-पैचिंग के साथ क्या गलत है, इसकी जड़ वास्तव में है: एक गुप्त चैनल वैश्विक, छुपे हुए माध्यमों के माध्यम से स्पष्टता और पारदर्शिता के बिना परिचालन करता है। इस मूल वैचारिक समस्या से सभी व्यावहारिक समस्याओं को समझ में आता है।

I दृढ़ता से आपको उप-वर्गीकरण जैसे स्वच्छ समाधानों के पक्ष में बंदर-पैचिंग को अस्वीकार करने का आग्रह करता हूं।

+0

बंदर पैचिंग और इसकी संभावित समस्याओं के इस स्पष्ट वर्णन के लिए धन्यवाद! मुझे कहना होगा कि NumPy उन्हें समर्थन करके "कुछ के सरणी" की परिभाषा को प्रोत्साहित करता है ('numpy.array ([any_object])')। तो, मैं कहूंगा कि "किसी भी प्रकार की वस्तु के matrices" एक अवधारणा है जो NumPy-element-wise अतिरिक्त द्वारा समर्थित है स्वचालित रूप से समर्थित है आदि। उसने कहा, मैं पूरी तरह से आपकी प्रतिक्रिया की सदस्यता लेता हूं! – EOL

1

सामान्य में, यह पूरी तरह तरीके हैं कि ओवरराइड करने के लिए स्वीकार्य है ...

  • जानबूझकर ओवरराइड की अनुमति
  • एक तरह से वे दस्तावेज़ (संतोषजनक LSP चोट नहीं होगा)

तो में दोनों स्थितियों को पूरा किया जाता है, फिर ओवरराइडिंग सुरक्षित होना चाहिए।

+1

एलएसपी के बारे में दिलचस्प लिंक! – EOL

1

"redefine" के साथ आपका क्या मतलब है इस पर निर्भर करता है। जाहिर है आप इसके अपने संस्करण का उपयोग कर सकते हैं, कोई समस्या नहीं है। यदि आप एक विधि है तो आप सबक्लासिंग द्वारा इसे फिर से परिभाषित कर सकते हैं।

आप एक नई विधि भी बना सकते हैं, और इसे कक्षा में पैच कर सकते हैं, एक अभ्यास जिसे monkey_patching के नाम से जाना जाता है। इसलिए जैसा:

from amodule import aclass 

def newfunction(self, param): 
    do_something() 

aclass.oldfunction = newfunction 

यह Aclass के सभी उदाहरणों, पुराने एक के बजाय अपने नए फ़ंक्शन का उपयोग किसी भी "चतुर्थ-पक्ष" मॉड्यूल में उदाहरण सहित कर देगा। यह काम करता है और बहुत उपयोगी है, लेकिन इसे बहुत बदसूरत और अंतिम उपाय विकल्प माना जाता है। ऐसा इसलिए है क्योंकि क्लास कोड में कुछ भी नहीं है यह सुझाव देने के लिए कि आपने विधि को ओवरराइड कर दिया है, इसलिए डीबग करना मुश्किल है। और इससे भी बदतर हो जाता है जब दो मॉड्यूल एक ही चीज़ बंद कर देते हैं। फिर आप वास्तव में भ्रमित हो जाते हैं।

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

  • कोई संबंधित समस्या नहीं^_^