2010-07-05 10 views
13

मैं एक वस्तु को परिभाषित कर सकते हैं और गुण और तरीकों में निर्दिष्ट करें:ऑब्जेक्ट्स या क्लोजर - कब उपयोग करें?

class object: 
    def __init__(self,a,b): 
     self.a = a 
     self.b = b 
    def add(self): 
     self.sum = self.a + self.b 
    def subtr(self): 
     self.fin = self.sum - self.b 
    def getpar(self): 
     return self.fin 

obj = object(2,3) 
obj.add() 
obj.subtr() 
obj.getpar() 

या बंद करने को परिभाषित करते हुए एक ही कार्यक्षमता प्रदान:

def closure(a,b): 
    par = {} 
    def add(): 
     par.update({'sum':a+b}) 
    def subtr(): 
     par.update({'fin':par['sum']-b}) 
    def getpar(): 
     return par['fin'] 
    return {'add':add,'subtr':subtr,'getpar':getpar} 

clos = closure(2,3) 
clos['add']() 
clos['subtr']() 
clos['getpar']() 

मुझे लगता है कि वस्तु वाक्य रचना सबसे दर्शकों के लिए क्लीनर लगेगा, लेकिन क्या ऐसे उदाहरण हैं जिनमें बंद होने का उपयोग अर्थात् बेहतर होगा?

+1

यह भी देखें http://stackoverflow.com/questions/256625/when-to-use-closure/256651#256651। ;) – FMc

+1

:) हां स्टीफन को क्यूसी ना के तहत अध्ययन करना चाहिए। – Yuji

+0

क्या वह अभी भी शिक्षकों को ले रहा है? :) – hatmatrix

उत्तर

7

पायथन में, बंद करने और अधिक सामान्य वस्तुओं की तुलना में उपयोग करने के लिए कठिन हो सकता है (आपको कॉलबेल को कहीं सेव करना होगा, उन्हें गुमराह नोटेशन clos['add'] आदि के साथ एक्सेस करें ...)। उदाहरण के लिए sum तक पहुंचने की असंभवता यदि आपको परिणाम में कुछ अजीब लगता है ... इस तरह की चीज को डिबग करना वास्तव में कठिन हो सकता है ;-)

केवल वास्तविक क्षतिपूर्ति लाभ सादगी है - लेकिन यह मूल रूप से केवल लागू होता है वास्तव में सरल मामलों के लिए (जब तक आपके पास तीन कॉलबेल होते हैं जो आंतरिक कार्य होते हैं तो मैं कहूंगा कि आप उस सम्मान में ओवरबोर्ड हैं)।

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

+0

कक्षाओं के लिए बेहतर डीबगिंग समर्थन के बारे में सच है ... – hatmatrix

+0

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

1

कक्षा के लिए कॉलिंग वाक्यविन्यास अच्छा दिखता है और आप वर्गों को उप-वर्ग कर सकते हैं। बंद करने में return कथन में उन सभी नामों को दोहराया जाना शामिल है जिन्हें आप बेनकाब करना चाहते हैं। शायद यह ठीक है यद्यपि यदि आप वास्तव में निजी विधियों को सामान्य अंडरस्कोर उपसर्ग सम्मेलन

+0

हां, मैं अक्सर उप-वर्ग नहीं करता लेकिन यह – hatmatrix

+0

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

15

से अधिक छिपे हुए हैं, तो आपको उस संस्करण का उपयोग करना चाहिए जो आप स्पष्ट रूप से व्यक्त करने की कोशिश कर रहे हैं।

दिए गए उदाहरण में, मैं कहूंगा कि ऑब्जेक्ट संस्करण अधिक स्पष्ट है, क्योंकि ऐसा लगता है कि यह स्थिति के साथ एक ऑब्जेक्ट मॉडलिंग कर रहा है। मान का उपयोग करने वाले कोड को देखते हुए, ऑब्जेक्ट संस्करण स्पष्ट इरादा व्यक्त करता है, जबकि बंद संस्करण में ऑपरेशन (इंडेक्सिंग और 'जादू' तार) होते हैं जो बिंदु के बगल में होते हैं।

पायथन में, जब आवश्यक हो तो मैं एक बंद आधारित दृष्टिकोण का पक्ष लेता हूं जो अधिकतर एक समारोह की तरह होता है, और शायद कुछ राज्य को पकड़ने की आवश्यकता होती है।

def tag_closure(singular, plural): 
    def tag_it(n): 
     if n == 1: 
      return "1 " + singular 
     else: 
      return str(n) + " " + plural 
    return tag_it 

t_apple = tag_closure("apple", "apples") 
t_cherry = tag_closure("cherry", "cherries"); 
print t_apple(1), "and", t_cherry(15) 

यह शायद निम्नलिखित की तुलना में थोड़ा स्पष्ट है:

class tag_object(object): 
    def __init__(self, singular, plural): 
     self.singular = singular 
     self.plural = plural 

    def tag(self, n): 
     if n == 1: 
      return "1 " + self.singular 
     else: 
      return str(n) + " " + self.plural 

t_apple = tag_object("apple", "apples") 
t_cherry = tag_object("cherry", "cherries"); 
print t_apple.tag(1), "and", t_cherry.tag(15) 

अंगूठे का एक नियम के रूप में: अगर बात वास्तव में केवल एक ही कार्य है, और यह केवल स्थिर राज्य पर कब्जा है, तो पर विचार एक बंद यदि चीज का उद्देश्य म्यूटेबल राज्य है, और/या एक से अधिक फ़ंक्शन हैं, तो कक्षा का उपयोग करें।

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

+2

+1। – spade78

3

बंद करने का उपयोग करने के लिए मैं केवल एक वास्तविक कारण देख सकता हूं, यदि आप बल्कि मजबूत गारंटी चाहते हैं कि आपके ऑब्जेक्ट/क्लोजर के उपयोगकर्ता को एक छिपे हुए चर तक पहुंच नहीं है।

कुछ इस तरह:

class Shotgun: 
    def __init__(self): 
     me = {} 
     me['ammo'] = 2 
     def shoot(): 
     if me['ammo']: 
      me['ammo'] -= 1 
      print "BANG" 
     else: 
      print "Click ..." 
     self.shoot = shoot 

s = Shotgun() 
s.shoot() 
s.shoot() 
s.shoot() 
+3

मुझे यकीन नहीं है कि हम वैरिएबल निजी बनाने के तरीके के रूप में बंद होने पर भरोसा कर सकते हैं। कोई 's.shoot.func_closure [0] .cell_contents ['ammo'] = 1e20' – unutbu

+0

के साथ' s = शॉटगन() 'को पुनः प्राप्त कर सकता है। किसी भी सुरक्षा के लिए इस पर भरोसा करना वास्तव में एक अच्छा विचार नहीं है। – phoku

+2

कम से कम 'obj.variable =' नोटेशन का उपयोग करके क्लास ऑब्जेक्ट के आंतरिक भाग तक पहुंचने से एक बंद होने में अच्छी तरह से खुदाई लगती है। – spade78

1

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

मुझे उत्सुकता है कि यह दृष्टिकोण खराब चीजें करता है जिनके बारे में मुझे पता नहीं है।

def closure(a, b): 
    def add(): 
     closure.sum = a + b 
    def subtr(): 
     closure.fin = closure.sum - b 
    def getpar(): 
     return closure.fin 
    closure.add = add; 
    closure.subtr = subtr 
    closure.getpar = getpar 
    return closure 

clo = closure(2,3) 
clo.add() 
clo.subtr() 
print(clo.getpar()) 
print(clo.sum) 
print(clo.fin) 
संबंधित मुद्दे