अजगर, डेल या डेल्ट्रा में कौन सा बेहतर है?


181

यह मूर्खतापूर्ण हो सकता है, लेकिन यह थोड़ी देर के लिए मेरे मस्तिष्क के पीछे की ओर घूम रहा है।

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

del foo.bar
delattr(foo, "bar")

लेकिन मैं सोच रहा हूं कि क्या उन दोनों के बीच अंडर-हूड मतभेद हो सकता है।

जवाबों:


266

पहला दूसरे की तुलना में अधिक कुशल है। del foo.barदो बाइटकोड निर्देशों के संकलन:

  2           0 LOAD_FAST                0 (foo)
              3 DELETE_ATTR              0 (bar)

जबकि delattr(foo, "bar")पाँच लगते हैं:

  2           0 LOAD_GLOBAL              0 (delattr)
              3 LOAD_FAST                0 (foo)
              6 LOAD_CONST               1 ('bar')
              9 CALL_FUNCTION            2
             12 POP_TOP             

यह पहले थोड़े तेज़ चलने में अनुवाद करता है (लेकिन यह बहुत बड़ा अंतर नहीं है - मेरी मशीन पर .15 μs)।

जैसा कि दूसरों ने कहा है, आपको वास्तव में केवल दूसरे रूप का उपयोग करना चाहिए जब आप जिस विशेषता को हटा रहे हैं वह गतिशील रूप से निर्धारित किया गया है।

[एक फ़ंक्शन के अंदर उत्पन्न बायोटेक निर्देशों को दिखाने के लिए संपादित किया जाता है, जहां कंपाइलर उपयोग कर सकता है LOAD_FASTऔर LOAD_GLOBAL]


6
इसे उत्पन्न करने के लिए आपने किस टूल का उपयोग किया?
त्रिकोणीय जूल

33
disमॉड्यूल। आप इसे कमांड लाइन से उपयोग कर सकते हैं python -m disऔर कुछ कोड में टाइप कर सकते हैं, या इसके साथ एक फ़ंक्शन डिसाइड कर सकते हैं dis.dis()
माइल्स

15
सभी बुराईयो की जड़ समयपूर्व इष्टतमीकरण है। ;-) लेकिन हाँ, आप सही हैं, बिल्कुल।
लेन्नर्ट रेगेब्र जूल

26
..तो क्या यह पालन करता है कि पैसे का प्यार समय से पहले अनुकूलन है?
जॉन फोहि

5
समयपूर्व अनुकूलन पैसे के प्यार का एक सबसेट है, क्योंकि इसका मतलब है कि आप प्रसंस्करण शक्ति पर कम खर्च करने की कोशिश कर रहे हैं :)
रोब अनुदान

41
  • डेल अधिक स्पष्ट और कुशल है;
  • डेल्टा गतिशील विशेषता को हटाने की अनुमति देता है।

निम्नलिखित उदाहरणों पर विचार करें:

for name in ATTRIBUTES:
    delattr(obj, name)

या:

def _cleanup(self, name):
    """Do cleanup for an attribute"""
    value = getattr(self, name)
    self._pre_cleanup(name, value)
    delattr(self, name)
    self._post_cleanup(name, value)

आप इसे डेल के साथ नहीं कर सकते ।


2
आप डेल के साथ दूसरा एक कर सकते हैं। del self.__dict__[name]यह मानते हुए कि मेटा क्लास के साथ कोई मज़ेदार व्यवसाय नहीं चल रहा है
smac89

17

निर्विवाद रूप से पूर्व। मेरे विचार में यह पूछने जैसा foo.barहै कि क्या इससे बेहतर है getattr(foo, "bar"), और मुझे नहीं लगता कि कोई भी उस सवाल को पूछ रहा है :)


3
मुझे यकीन है कि वहाँ कम से कम एक व्यक्ति है जो foo.bar पर getattr (फू, "बार") को पसंद करेगा। दी, मैं उनसे सहमत नहीं हूँ। लेकिन यह एक व्यक्ति अभी भी पर्याप्त है ताकि यह निर्विवाद रूप से पूर्व न हो।
जेसन बेकर

3
@ जैसन तब वाक्यांश की आपकी व्याख्या से किसी भी चीज़ की तुलना में "निर्विवाद रूप से बेहतर" नहीं है। मुझे लगता है कि यह "निर्विवाद रूप से" का पूरी तरह से उचित उपयोग है।
फोब

26
जब कोई संभावना हो कि संपत्ति मौजूद नहीं है और आप किसी डिफ़ॉल्ट मान को सेट किए बिना लिखने की कोशिश करना चाहते हैं तो गेटअटर बेहतर है। अर्थात। gettattr (फू, "बार", कोई नहीं)
मार्क गिबन्स

2
@MarcGibbons: रुको, यह एक बात है? मैंने हमेशा पैटर्न का उपयोग किया है if hasattr(obj, 'var') and obj.var == ...... मैं इसे if getattr(obj, 'var', None) == ...ज्यादातर मामलों में कम कर सकता हूं ! थोड़ा कम और पढ़ने में आसान, मुझे लगता है।
आर्टऑफवर्फ

@ArtOfWarfare hasattrअसल में कॉल करती हैgetattr
cheniel

14

यह वास्तव में वरीयता की बात है, लेकिन पहला शायद बेहतर है। यदि आप उस विशेषता का नाम नहीं जानते हैं जिसे आप समय से पहले हटा रहे हैं तो मैं केवल दूसरे का उपयोग करूंगा।


5

गेटअटर और सेटट्रा की तरह, डेल्टा का उपयोग केवल तब किया जाना चाहिए जब विशेषता नाम अज्ञात हो।

इस अर्थ में, यह कई पायथन विशेषताओं के लगभग समान है जो कि सामान्य रूप से आपके द्वारा उपलब्ध की __import__बजाय निम्न स्तर पर निर्मित कार्यक्षमता का उपयोग करने के लिए उपयोग किया जाता है, जैसे कि importऔर operator.addइसके बजाय+


3

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


1

यदि आपको लगता delattrहै कि अधिक स्पष्ट है, तो getattrइसके बजाय हर समय उपयोग क्यों नहीं किया जाता है object.attr?

हुड के तहत के रूप में ... तुम्हारा अनुमान मेरा जितना अच्छा है। अगर काफी बेहतर नहीं है।


1

यह एक पुराना सवाल है, लेकिन मैं अपने 2 सेंट लगाना चाहूंगा।

हालांकि, del foo.barअधिक सुरुचिपूर्ण है, कई बार आपको आवश्यकता होगी delattr(foo, "bar")। कहते हैं, यदि आपके पास एक इंटरैक्टिव कमांड लाइन इंटरफ़ेस है जो उपयोगकर्ता को नाम टाइप करके ऑब्जेक्ट में किसी भी सदस्य को गतिशील रूप से हटाने की अनुमति देता है , तो आपके पास बाद के फॉर्म का उपयोग करने के अलावा कोई विकल्प नहीं है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.