दिलचस्प पोस्ट
NUnit Visual Studio 2010 कोड नहीं चल रहा है क्यों नहीं Perl मेरी फाइल है जो ClearCase में है ढूँढ सकते हैं? पायथन कोई भी तुलना नहीं: क्या मुझे "है" या == का उपयोग करना चाहिए? एक प्रोग्राम में OpenSSL पुस्तकालयों को लिंक करना जावा में स्कैनर वर्ग का उपयोग करके कंसोल से इनपुट कैसे पढ़ सकता हूं? एकाधिक async कार्यों को चलाने और उन्हें पूरा करने के लिए सभी के लिए प्रतीक्षा कर रहा है मुझे कब तैयार बयानों का उपयोग करना चाहिए? मैं कैसे एक jQuery स्क्रॉल घटना की दिशा निर्धारित कर सकते हैं? मैं git में अगले प्रतिबद्ध कैसे मिल सकता है? जावा से एक फ़ोल्डर में सभी फाइलें कैसे पढ़ती हैं? एंड्रॉइड: एंड्रॉइड मार्केट जैसी अनन्त सूची के लिए प्रगति पट्टी को लागू करना और "लोड हो रहा है …" क्या इस जावास्क्रिप्ट मुहावरे कम है: var स्वयं = यह? NetBeans में एक JAR कैसे जोड़ें मैं क्षैतिज <यूएल> मेनू कैसे संरेखित करूं? रॉ पोस्ट PHP में curl का उपयोग कर

पायथन में @staticmethod और @classmethod के बीच अंतर क्या है?

@staticmethod और @staticmethod साथ सजाए गए फ़ंक्शन के बीच अंतर क्या है?

वेब के समाधान से एकत्रित समाधान "पायथन में @staticmethod और @classmethod के बीच अंतर क्या है?"

हो सकता है कि उदाहरण कोड का थोड़ा सा मदद मिलेगा: foo , class_foo और static_foo के कॉल हस्ताक्षर में अंतर static_foo :

 class A(object): def foo(self,x): print "executing foo(%s,%s)"%(self,x) @classmethod def class_foo(cls,x): print "executing class_foo(%s,%s)"%(cls,x) @staticmethod def static_foo(x): print "executing static_foo(%s)"%xa=A() 

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

 a.foo(1) # executing foo(<__main__.A object at 0xb7dbef0c>,1) 

क्लासमेप्थ के साथ , ऑब्जेक्ट इंस्टेंस के क्लास को self बजाय पहली तर्क के रूप में पारित किया जाता है

 a.class_foo(1) # executing class_foo(<class '__main__.A'>,1) 

आप कक्षा का उपयोग करके class_foo भी कॉल कर सकते हैं। वास्तव में, यदि आप कुछ को एक वर्ग पद्धति के रूप में परिभाषित करते हैं, तो शायद यह संभव है क्योंकि आप इसे क्लास इंस्टेंस से बजाय क्लास से कॉल करने का इरादा रखते हैं। A.foo(1) ने एक TypeError उठाया होगा, लेकिन A.class_foo(1) केवल ठीक काम करता है:

 A.class_foo(1) # executing class_foo(<class '__main__.A'>,1) 

लोगों को एक तरह से क्लास के तरीकों के लिए मिला है इनहेरिट करने योग्य वैकल्पिक कन्स्ट्रक्टर बनाने के लिए।


स्थैतिक तरीकों के साथ , न तो self (वस्तु उदाहरण) और न ही cls (कक्षा) को पहली तर्क के रूप में पारित किया जाता है वे सादे कार्यों की तरह व्यवहार करते हैं, सिवाय इसके कि आप उन्हें एक उदाहरण या कक्षा से कॉल कर सकते हैं:

 a.static_foo(1) # executing static_foo(1) A.static_foo('hi') # executing static_foo(hi) 

Staticmethods समूह कार्यों के लिए उपयोग किया जाता है, जो कक्षा के लिए कक्षा के साथ कुछ तार्किक कनेक्शन हैं।


foo सिर्फ एक फ़ंक्शन है, लेकिन जब आप a.foo कहते हैं, तो आप फ़ंक्शन को प्राप्त नहीं करते हैं, तो आप फंक्शन के पहले तर्क के रूप में वस्तु आवृत्ति के साथ एक "आंशिक रूप से लागू" संस्करण प्राप्त करते हैं। foo को 2 तर्कों की उम्मीद है, जबकि a.foo केवल 1 तर्क की अपेक्षा करता है।

a foo लिए बाध्य है इसका मतलब नीचे "बाध्य" शब्द का क्या मतलब है:

 print(a.foo) # <bound method A.foo of <__main__.A object at 0xb7d52f0c>> 

a.class_foo साथ, a a.class_foo के लिए बाध्य नहीं है, बल्कि क्लास A class_foo लिए बाध्य है।

 print(a.class_foo) # <bound method type.class_foo of <class '__main__.A'>> 

यहाँ, एक staticmethod के साथ, भले ही यह एक विधि है, a.static_foo सिर्फ एक अच्छा 'ऑब्जेक्ट लिंकिंग एंड एम्बेडिंग फ़ंक्शन देता है जिसमें कोई तर्क नहीं है। static_foo को 1 तर्क की उम्मीद है, और a.static_foo 1 तर्क को भी उम्मीद करता है

 print(a.static_foo) # <function static_foo at 0xb7d479cc> 

और निश्चित रूप से एक ही बात तब होती है जब आप static_foo को क्लास A बजाय कॉल करते हैं।

 print(A.static_foo) # <function static_foo at 0xb7d479cc> 

एक स्थैतिक विधि एक ऐसा तरीका है जिसे कक्षा या उदाहरण के बारे में कुछ भी नहीं पता है जिसे इसे पर बुलाया गया था। यह सिर्फ उन तर्कों को पारित कर दिया गया जो पारित किए गए थे, कोई भी पहला तर्क नहीं था। यह मूल रूप से पायथन में बेकार है – आप केवल एक staticmethod की बजाय एक मॉड्यूल फ़ंक्शन का उपयोग कर सकते हैं।

दूसरी ओर, एक क्लासमेपथ, एक ऐसा तरीका है जिसे उस क्लास को पारित किया जाता है जिसे उस पर बुलाया गया था, या उस आवृत्ति का वर्ग जिसे पहले तर्क दिया गया था, पहले तर्क के रूप में। यह तब उपयोगी होता है जब आप पद्धति को कक्षा के लिए एक कारखाना बनाना चाहते हैं: चूंकि यह वास्तविक श्रेणी प्राप्त करता है, इसे पहली तर्क के रूप में बुलाया गया था, आप हमेशा सही वर्ग को इन्स्तांत कर सकते हैं, भले ही उप-वर्ग शामिल हों। उदाहरण के लिए देखें कि कैसे dict.fromkeys() , एक क्लासमैथ, एक उप-वर्ग पर कॉल किए जाने वाले उपवर्ग का एक उदाहरण देता है:

 >>> class DictSubclass(dict): ... def __repr__(self): ... return "DictSubclass" ... >>> dict.fromkeys("abc") {'a': None, 'c': None, 'b': None} >>> DictSubclass.fromkeys("abc") DictSubclass >>> 

मूलतः @classmethod एक विधि बनाता है जिसका पहला तर्क क्लास से होता है (क्लास इंस्टेंस के बजाय), @staticmethod में कोई निहित तर्क नहीं है।

आधिकारिक अजगर दस्तावेज़:

@classmethod

एक क्लास पद्धति को क्लास को पहली तर्क के रूप में प्राप्त होता है, उदाहरण के उदाहरण की तरह उदाहरण प्राप्त होता है। क्लास विधि को घोषित करने के लिए, इस मुहावरे का उपयोग करें:

 class C: @classmethod def f(cls, arg1, arg2, ...): ... 

@classmethod फॉर्म फ़ंक्शन डेकोरेटर है – विवरण के लिए फ़ंक्शन परिभाषाओं में फ़ंक्शन परिभाषाओं का विवरण देखें।

इसे या तो क्लास पर (जैसे Cf() ) या एक उदाहरण (जैसे C().f() ) कहा जा सकता है। इसकी कक्षा को छोड़कर उदाहरण को अनदेखा किया गया है। यदि एक क्लास विधि को व्युत्पन्न वर्ग के लिए कहा जाता है, तो व्युत्पन्न वर्ग ऑब्जेक्ट निहित पहला तर्क के रूप में पारित किया जाता है।

कक्षा के तरीकों सी + + या जावा स्थिर तरीकों से अलग हैं यदि आप उनको चाहते हैं, तो इस खंड में staticmethod() देखें।

@staticmethod

एक स्थिर विधि को एक अन्तर्निहित पहली तर्क प्राप्त नहीं होता है एक स्थिर विधि घोषित करने के लिए, इस मुहावरे का उपयोग करें:

 class C: @staticmethod def f(arg1, arg2, ...): ... 

@staticmethod फॉर्म फ़ंक्शन डेकोरेटर है – विवरण के लिए फ़ंक्शन परिभाषाओं में फ़ंक्शन परिभाषाओं का विवरण देखें।

इसे या तो क्लास पर (जैसे Cf() ) या एक उदाहरण (जैसे C().f() ) कहा जा सकता है। इसकी कक्षा को छोड़कर उदाहरण को अनदेखा किया गया है।

पायथन में स्टेटिक विधियां, जावा या सी ++ में पाए जाने वाले समान हैं अधिक उन्नत अवधारणा के लिए, इस खंड में classmethod() देखें।

इस प्रश्न पर एक संक्षिप्त लेख यहां दिया गया है

@staticmethod फ़ंक्शन किसी वर्ग के अंदर निर्धारित फ़ंक्शन से कुछ और नहीं है। यह पहली बार क्लास को शुरु किए बिना दायित्व है यह परिभाषा विरासत के माध्यम से अपरिवर्तनीय है

@ वर्गमैनेशन फ़ंक्शन क्लास को तत्काल बिना भी दायित्व देता है, लेकिन इसकी परिभाषा उप-कक्षा, विरासत के जरिए, मूल वर्ग नहीं है। ऐसा इसलिए है क्योंकि @classmethod फ़ंक्शन के लिए पहला तर्क हमेशा सीएलएस (क्लास) होना चाहिए।

पायथन में @staticmethod और @classmethod के बीच अंतर क्या है?

आपने इस सीडोडोडो की तरह पाइथन कोड देखा हो सकता है, जो विभिन्न विधि प्रकारों के हस्ताक्षर को दर्शाता है और प्रत्येक को समझाने के लिए एक डॉसस्ट्रिंग प्रदान करता है:

 class Foo(object): def a_normal_instance_method(self, arg_1, kwarg_2=None): ''' Return a value that is a function of the instance with its attributes, and other arguments such as arg_1 and kwarg2 ''' @staticmethod def a_static_method(arg_0): ''' Return a value that is a function of arg_0. It does not know the instance or class it is called from. ''' @classmethod def a_class_method(cls, arg1): ''' Return a value that is a function of the class and other arguments. respects subclassing, it is called with the class it is called from. ''' 

सामान्य उदाहरण विधि

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

उदाहरण के लिए, यह एक स्ट्रिंग का उदाहरण है:

 ', ' 

यदि हम उदाहरण पद्धति का उपयोग करते हैं, तो इस स्ट्रिंग पर जुड़ें, एक और पुनरावृत्त में शामिल होने के लिए, यह काफी स्पष्ट रूप से उदाहरण के एक समारोह है, इसके अलावा, उस सूची के कार्य के अलावा, ['a', 'b', 'c'] :

 >>> ', '.join(['a', 'b', 'c']) 'a, b, c' 

बाध्य तरीके

उदाहरण के तरीकों को बाद में उपयोग के लिए एक बिन्दु देखरेख के माध्यम से बाध्य किया जा सकता है।

उदाहरण के लिए, यह str.join विधि को ':' उदाहरण के साथ जोड़ता है:

 >>> join_with_colons = ':'.join 

और बाद में हम इसका उपयोग उस फ़ंक्शन के रूप में कर सकते हैं, जो पहले से ही उस तर्क से जुड़ी पहली तर्क है। इस तरह, यह उदाहरण पर आंशिक फ़ंक्शन की तरह काम करता है:

 >>> join_with_colons('abcde') 'a:b:c:d:e' >>> join_with_colons(['FF', 'FF', 'FF', 'FF', 'FF', 'FF']) 'FF:FF:FF:FF:FF:FF' 

स्थैतिक विधि

स्थैतिक विधि एक तर्क के रूप में उदाहरण नहीं लेता है

यह एक मॉड्यूल स्तर फ़ंक्शन के समान है।

हालांकि, एक मॉड्यूल स्तर की फ़ंक्शन मॉड्यूल में ही रहना चाहिए और विशेष रूप से अन्य स्थानों पर आयात किया जाना चाहिए जहां इसका उपयोग किया जाता है।

यदि यह ऑब्जेक्ट से जुड़ा हुआ है, हालांकि, यह सामान आयात और विरासत के माध्यम से सुविधाजनक रूप से भी पालन करेगा।

एक स्थिर विधि का एक उदाहरण str.maketrans , string मॉड्यूल से अजगर 3 में ले जाया गया। यह str.translate द्वारा खपत के लिए उपयुक्त अनुवाद तालिका बनाता है। स्ट्रिंग के एक उदाहरण से प्रयोग किया जाता है, लेकिन यह string मॉड्यूल से फ़ंक्शन आयात करने के बजाय यह बेवकूफी है, और यह क्लास से कॉल करने में सक्षम होना अच्छा है, जैसे str.maketrans

 # demonstrate same function whether called from instance or not: >>> ', '.maketrans('ABC', 'abc') {65: 97, 66: 98, 67: 99} >>> str.maketrans('ABC', 'abc') {65: 97, 66: 98, 67: 99} 

अजगर 2 में, आपको इस फ़ंक्शन को अधिक कम उपयोगी स्ट्रिंग मॉड्यूल से आयात करना होगा:

 >>> import string >>> 'ABCDEFG'.translate(string.maketrans('ABC', 'abc')) 'abcDEFG' 

कक्षा विधि

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

बिल्टिन क्लासमेपमेंट का सबसे विहित उदाहरण dict.fromkeys है। इसका उपयोग डिक्की के एक वैकल्पिक कन्स्ट्रक्टर के रूप में किया जाता है, (जब आप जानते हैं कि आपकी चाबियाँ क्या हैं और उनके लिए एक डिफ़ॉल्ट मान चाहते हैं तो यह उपयुक्त है।)

 >>> dict.fromkeys(['a', 'b', 'c']) {'c': None, 'b': None, 'a': None} 

जब हम उप-वर्गीकृत करते हैं, तो हम उसी निर्माता का उपयोग कर सकते हैं, जो उपवर्ग का एक उदाहरण बनाता है।

 >>> class MyDict(dict): 'A dict subclass, use to demo classmethods' >>> md = MyDict.fromkeys(['a', 'b', 'c']) >>> md {'a': None, 'c': None, 'b': None} >>> type(md) <class '__main__.MyDict'> 

वैकल्पिक कन्स्ट्रक्शंस के अन्य समान उदाहरणों के लिए पांडा स्रोत कोड देखें, और classmethod और staticmethod पर आधिकारिक पायथन दस्तावेज़ीकरण भी देखें।

तय करने के लिए कि क्या @staticmethod या @classmethod का उपयोग करना है, आपको अपनी विधि के अंदर देखना होगा यदि आपकी पद्धति आपके वर्ग में अन्य चर / विधियों तक पहुंच जाती है, तो @classmethod का उपयोग करें दूसरी ओर यदि आपकी विधि कक्षा के किसी भी अन्य हिस्से को छूती नहीं है, तो @staticmethod का उपयोग करें

 class Apple: _counter = 0 @staticmethod def about_apple(): print('Apple is good for you.') # note you can still access other member of the class # but you have to use the class instance # which is not very nice, because you have repeat yourself # # For example: # @staticmethod # print('Number of apples have been juiced: %s' % Apple._counter) # # @classmethod # print('Number of apples have been juiced: %s' % cls._counter) # # @classmethod is especially useful when you move your function to other class, # you don't have to rename the class reference @classmethod def make_apple_juice(cls, number_of_apples): print('Make juice:') for i in range(number_of_apples): cls._juice_this(i) @classmethod def _juice_this(cls, apple): print('Juicing %d...' % apple) cls._counter += 1 

@ डीकोरेटरों को अजगर 2.4 में जोड़ा गया था। यदि आप अजगर <2.4 का उपयोग कर रहे हैं तो आप classmethod () और staticmethod () फ़ंक्शन का उपयोग कर सकते हैं।

उदाहरण के लिए, यदि आप एक कारखाना पद्धति बनाना चाहते हैं (एक फ़ंक्शन जो एक क्लास के भिन्न कार्यान्वयन की एक आवृत्ति को लौटाता है, उसके आधार पर यह तर्क क्या होता है) आप ऐसा कुछ कर सकते हैं:

 class Cluster(object): def _is_cluster_for(cls, name): """ see if this class is the cluster with this name this is a classmethod """ return cls.__name__ == name _is_cluster_for = classmethod(_is_cluster_for) #static method def getCluster(name): """ static factory method, should be in Cluster class returns a cluster object for the given name """ for cls in Cluster.__subclasses__(): if cls._is_cluster_for(name): return cls() getCluster = staticmethod(getCluster) 

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

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

मुझे लगता है कि एक बेहतर सवाल यह है कि "आप @ वर्गमैथेशन बनाम @staticmethod का उपयोग कब करेंगे?"

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

@staticmethod सीमांत प्रदर्शन लाभ प्रदान करता है, लेकिन मुझे कक्षा के बाहर एक स्टैंडअलोन फ़ंक्शन के रूप में प्राप्त नहीं की जा सकने वाली कक्षा में स्थिर विधि का एक उत्पादक उपयोग अभी तक नहीं देखा गया है।

स्थिर तरीके:

  • कोई आत्म तर्क के साथ सरल कार्य
  • कक्षा विशेषताओं पर कार्य; उदाहरण के गुण पर नहीं
  • दोनों वर्ग और उदाहरण के माध्यम से कहा जा सकता है।
  • अंतर्निर्मित कार्य staticmethod () उन्हें बनाने के लिए उपयोग किया जाता है

स्थिर तरीकों के लाभ:

  • यह क्लासस्कोप में फंक्शन नाम को स्थानांतरित करता है
  • यह उस समारोह कोड के करीब स्थानांतरित करता है जहां इसका उपयोग किया जाता है
  • प्रत्येक विधि से विशेष रूप से आयात करने की आवश्यकता नहीं है क्योंकि बनाम मॉड्यूल-स्तर कार्यों को आयात करने के लिए और अधिक सुविधाजनक

     @staticmethod def some_static_method(*args, **kwds): pass 

कक्षा के तरीकों:

  • फ़ंक्शन जिनमें क्लासनाम के रूप में पहला तर्क होता है
  • दोनों वर्ग और उदाहरण के माध्यम से कहा जा सकता है।
  • ये क्लासमेथ इन-बिल्ट फ़ंक्शन के साथ बनाए गए हैं।

      @classmethod def some_class_method(cls, *args, **kwds): pass 

@staticmethod विधि डिस्क्रिप्टर के रूप में डिफ़ॉल्ट फ़ंक्शन को अक्षम करता है। क्लासमेनिस्ट आपके फ़ंक्शन को एक कंटेनर कॉल योग्य में लपेटता है जो कि मालिकाना वर्ग के संदर्भ को पहले तर्क के रूप में देता है:

 >>> class C(object): ... pass ... >>> def f(): ... pass ... >>> staticmethod(f).__get__(None, C) <function f at 0x5c1cf0> >>> classmethod(f).__get__(None, C) <bound method type.f of <class '__main__.C'>> 

तथ्य की बात के रूप में, classmethod में एक रनटाइम ओवरहेड है लेकिन मालिक वर्ग को एक्सेस करना संभव है। वैकल्पिक रूप से मैं एक मेटाक्लास का उपयोग करने और उस मेटाकल्स पर क्लास विधियों को डालने की सलाह देता हूं:

 >>> class CMeta(type): ... def foo(cls): ... print cls ... >>> class C(object): ... __metaclass__ = CMeta ... >>> C.foo() <class '__main__.C'> 

@ वर्गमैथि का अर्थ है : जब यह विधि बुलाया जाता है, तो हम उस क्लास के उदाहरण के बजाय क्लास को प्रथम तर्क के रूप में पास करते हैं (जैसा कि हम आम तौर पर तरीके से करते हैं) इसका अर्थ है कि आप एक विशिष्ट उदाहरण के बजाय उस विधि के भीतर कक्षा और उसकी संपत्ति का उपयोग कर सकते हैं।

@staticmethod का अर्थ है: जब यह विधि बुलाया जाता है, हम उसको कक्षा का एक उदाहरण नहीं देते (जैसा कि हम आमतौर पर तरीकों से करते हैं)। इसका मतलब है कि आप किसी वर्ग के अंदर एक फ़ंक्शन डाल सकते हैं, लेकिन आप उस क्लास के उदाहरण तक नहीं पहुंच सकते (यह उपयोगी है जब आपकी विधि इस उदाहरण का उपयोग नहीं करती है)।

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

@staticmethod फ़ंक्शन किसी वर्ग के अंदर निर्धारित फ़ंक्शन से कुछ और नहीं है। यह पहली बार क्लास को शुरु किए बिना दायित्व है यह परिभाषा विरासत के माध्यम से अपरिवर्तनीय है

  • अजगर को ऑब्जेक्ट के लिए एक बाध्य-विधि का इन्स्तांत नहीं करना पड़ता है।
  • यह कोड की पठनीयता को आसान बनाता है, और यह वस्तु की स्थिति पर निर्भर नहीं करता है;

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

  • कारखाने के तरीकों , जिसका उपयोग उदाहरण के लिए पूर्व प्रसंस्करण के कुछ प्रकार के उपयोग के लिए एक उदाहरण बनाने के लिए किया जाता है।
  • स्थैतिक तरीकों को बुलाए गए स्थिर तरीके : यदि आप कई स्थिर विधियों में एक स्थिर तरीके को विभाजित करते हैं, तो आपको क्लास के नाम को कठोर नहीं करना चाहिए, लेकिन वर्ग तरीकों का उपयोग करना चाहिए

स्थैतिक पद्धति बनाम वर्ग पद्धति के संबंध में एक अन्य विचार विरासत के साथ आता है। कहें कि आपके पास निम्न श्रेणी है:

 class Foo(object): @staticmethod def bar(): return "In Foo" 

और फिर आप बाल वर्ग में bar() ओवरराइड करना चाहते हैं:

 class Foo2(Foo): @staticmethod def bar(): return "In Foo2" 

यह काम करता है, लेकिन ध्यान रखें कि अब बाल क्लास ( Foo2 ) में bar() कार्यान्वयन उस क्लास के लिए विशिष्ट कुछ का लाभ नहीं ले सकता है। उदाहरण के लिए, Foo2 में magic() नामक एक विधि है, जिसे आप bar() के Foo2 कार्यान्वयन में उपयोग करना चाहते हैं:

 class Foo2(Foo): @staticmethod def bar(): return "In Foo2" @staticmethod def magic(): return "Something useful you'd like to use in bar, but now can't" 

यहां का समाधान Foo2.magic() को bar() Foo2.magic() में कॉल करने के लिए होगा, लेकिन फिर आप अपने आप को दोहरा रहे हैं (यदि Foo2 परिवर्तन का नाम है, तो आपको उस bar() विधि को अपडेट करना याद रखना होगा)।

मेरे लिए, यह खुले / बंद सिद्धांत का एक मामूली उल्लंघन है, क्योंकि Foo में किए गए फैसले से व्युत्पन्न वर्ग में सामान्य कोड को पुन: रिएक्ट करने की आपकी क्षमता पर असर Foo है (यानी यह विस्तार के लिए कम खुला है)। यदि bar() एक classmethod थे classmethod हम ठीक होंगे:

 class Foo(object): @classmethod def bar(cls): return "In Foo" class Foo2(Foo): @classmethod def bar(cls): return "In Foo2 " + cls.magic() @classmethod def magic(cls): return "MAGIC" print Foo2().bar() 

देता है: In Foo2 MAGIC

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

एक स्थैतिक विधि एक वर्ग के अंदर परिभाषित एक फ़ंक्शन है। यह वर्ग या उदाहरण के बारे में कुछ भी नहीं पता है जिसे उस पर बुलाया गया था और केवल उन तर्कों को प्राप्त किया जाता है जो किसी भी निहित प्रथम तर्क के बिना पारित हो जाते थे। उदाहरण:

 class Test(object): def foo(self, a): print "testing (%s,%s)"%(self,a) @classmethod def foo_classmethod(cls, a): print "testing foo_classmethod(%s,%s)"%(cls,a) @staticmethod def foo_staticmethod(a): print "testing foo_staticmethod(%s)"%a test = Test() 

staticmethods समूह कार्यों के लिए उपयोग किया जाता है, जो वर्ग के किसी वर्ग के साथ कुछ तार्किक कनेक्शन हैं।

मैं एक उदाहरण का उपयोग करके बुनियादी अंतर को समझाने की कोशिश करूंगा।

 class A(object): x = 0 def say_hi(self): pass @staticmethod def say_hi_static(): pass @classmethod def say_hi_class(cls): pass def run_self(self): self.x += 1 print self.x # outputs 1 self.say_hi() self.say_hi_static() self.say_hi_class() @staticmethod def run_static(): print Ax # outputs 0 # A.say_hi() # wrong A.say_hi_static() A.say_hi_class() @classmethod def run_class(cls): print cls.x # outputs 0 # cls.say_hi() # wrong cls.say_hi_static() cls.say_hi_class() 

1 – हम सीधे बिना स्थैतिक और क्लासम्प्लीसेस कॉल कर सकते हैं

 # A.run_self() # wrong A.run_static() A.run_class() 

2- स्थिर विधि स्व विधि को कॉल नहीं कर सकती है लेकिन अन्य स्थिर और क्लासमेप को कॉल कर सकती है

3- स्थैतिक विधि कक्षा से संबंधित है और ऑब्जेक्ट का उपयोग बिल्कुल भी नहीं किया जाएगा।

4- क्लास विधि किसी ऑब्जेक्ट के लिए बाध्य नहीं है बल्कि एक क्लास के लिए है।

@ वर्गमैथुन: उस वर्ग के बनाए सभी उदाहरणों के लिए एक साझा वैश्विक पहुंच बनाने के लिए इस्तेमाल किया जा सकता है ….. जैसे कि कई उपयोगकर्ताओं द्वारा एक रिकॉर्ड को अपडेट करना …. मुझे यह विशेष रूप से एकजुट बनाने के दौरान इसे फेल का उपयोग करने का पाया गया। )

@static method: इसके साथ जुड़े वर्ग या उदाहरण के साथ कुछ नहीं करना है … लेकिन पठनीयता के लिए स्थिर विधि का उपयोग कर सकते हैं

मैंने सी ++ और फिर जावा और फिर पायथन के साथ प्रोग्रामिंग भाषा सीखना शुरू कर दिया और इसलिए इस प्रश्न ने मुझे बहुत अधिक परेशान किया, जब तक कि मैं प्रत्येक के साधारण उपयोग को समझूं।

कक्षा विधि: जावा और सी + + के विपरीत पायथन कंस्ट्रक्टर ओवरलोडिंग नहीं करता है। और ऐसा करने के लिए आप classmethod उपयोग कर सकते हैं। निम्नलिखित उदाहरण इस समझाएंगे

मान लीजिए कि हमारे पास एक Person वर्ग है जो दो तर्क first_name और last_name लेता है और व्यक्ति का उदाहरण बनाता है।

 class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name 

अब, यदि आवश्यकता तब होती है जहां आपको केवल एक ही नाम का उपयोग करके एक वर्ग बनाने की आवश्यकता है, सिर्फ एक first_name आप अजथन में ऐसा कुछ नहीं कर सकते

यह आपको एक त्रुटि देगा, जब आप किसी वस्तु (उदाहरण) को बनाने का प्रयास करेंगे।

 class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name def __init__(self, first_name): self.first_name = first_name 

हालांकि, आप नीचे बताए गए @classmethod का उपयोग करके एक ही चीज़ प्राप्त कर सकते हैं

 class Person(object): def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name @classmethod def get_person(cls, first_name): return cls(first_name, "") 

स्थैतिक विधि:: यह एक बहुत ही सरल है, यह उदाहरण या वर्ग के लिए बाध्य नहीं है और आप साधारण कॉल कर सकते हैं कि क्लास का नाम प्रयोग कर रहे हैं

तो हम कहते हैं कि उपरोक्त उदाहरण में आपको एक सत्यापन की आवश्यकता है कि first_name 20 वर्णों से अधिक नहीं होनी चाहिए, आप ऐसा सरल कर सकते हैं।

@staticmethod def validate_name (name): वापसी लेन (नाम) <= 20

और आप कक्षा नाम का इस्तेमाल करते हुए सरल कॉल कर सकते थे

 Person.validate_name("Gaurang Shah") 

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

 class A(object): m=54 @classmethod def class_method(cls): print "m is %d" % cls.m 

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

 class X(object): m=54 #will not be referenced @staticmethod def static_method(): print "Referencing/calling a variable or function outside this class. Eg Some global variable/function." 
 #!/usr/bin/python #coding:utf-8 class Demo(object): def __init__(self,x): self.x = x @classmethod def addone(self, x): return x+1 @staticmethod def addtwo(x): return x+2 def addthree(self, x): return x+3 def main(): print Demo.addone(2) print Demo.addtwo(2) #print Demo.addthree(2) #Error demo = Demo(2) print demo.addthree(2) if __name__ == '__main__': main() 

IPython में एक दूसरे के समान तरीके से हैक-अप का पता चलता है कि @staticmethod सीमांत प्रदर्शन लाभ (नैनोसेकंड्स) में पैदा होता है, परन्तु अन्यथा यह कोई कार्य नहीं करता है इसके अलावा, किसी भी प्रदर्शन लाभ को संकलन के दौरान विधि के संसाधित करने के अतिरिक्त कार्य द्वारा संभवतः मिटा दिया जाएगा (जो किसी भी कोड निष्पादन से पहले होता है जब आप कोई स्क्रिप्ट चलाते हैं)।

कोड पठनीयता के लिए मैं जब तक आपकी विधि काम के भार के लिए इस्तेमाल नहीं किया जाएगा, जब तक कि नैनोसेकंड गिनती नहीं करते, मैं @staticmethod से बचना चाहता हूँ।