क्यों pycharm स्थिर करने के लिए विधि को बदलने का प्रस्ताव करता है


154

नया pycharm रिलीज़ (3.1.3 सामुदायिक संस्करण) उन तरीकों को परिवर्तित करने का प्रस्ताव करता है जो वर्तमान वस्तु की स्थिति के साथ काम नहीं करते हैं।

यहाँ छवि विवरण दर्ज करें

उसका व्यावहारिक कारण क्या है? किसी प्रकार का सूक्ष्म-प्रदर्शन (-ओर-मेमोरी) -ओपिमाइजेशन?


3
क्या आपने "अधिक ..." पर क्लिक किया? क्या आप selfविधि के अंदर कहीं भी संदर्भ देते हैं ? (यदि वास्तव में सवाल यह है कि "PyCharm के डिजाइनरों ने इसे इस तरह क्यों डिज़ाइन किया ... आपको उनसे पूछना होगा, न कि SO ...)
Wooble करें

7
@Wooble: return 1विधि की एकल पंक्ति कार्यान्वयन है। "अधिक" में कुछ भी उपयोगी नहीं है
9:14

जवाबों:


188

PyCharm "सोचता है" कि आप एक स्थिर विधि रखना चाहते थे , लेकिन आप इसे स्थिर ( @staticmethodसज्जाकार का उपयोग करके ) घोषित करना भूल गए ।

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


4
इतने सारे लोगों ने इस स्वाद प्रतिक्रिया के साथ जवाब दिया है। हालांकि, मुझे लगता है कि यदि आप जानते हैं कि यह निश्चित रूप से एक स्थिर विधि नहीं है, तो "फेंक NotImforceedError" को शामिल करें, जबकि आप निश्चित हैं कि आप इसे पूरा किए बिना उपयोग नहीं करते हैं।
रिचर्ड ग्रीन

1
ऐसे मामले भी हो सकते हैं, जिनमें PyCharm की चेतावनी अनुचित है कि हम न तो स्थैतिक तरीका चाहते हैं और न ही राज्य को बदलना चाहते हैं। दूसरी ओर, यदि विधि अभी तक लागू नहीं हुई है, तो यह हमेशा एक अच्छा विचार है कि ए बढ़ाएं NotImplementedError
जोलवी

3
मेरे पास ऐसा मामला है कि मेरा डिफ़ॉल्ट कार्यान्वयन स्थिर रहता है, लेकिन मेरे उपवर्गों के आधार पर मान लौटाने की अनुमति है self। इस मामले में चेतावनी उपेक्षित है, और मैं इसे चिह्नित करता हूं # noinspection PyMethodMayBeStatic। यह एक ख़ुशी की बात है कि IntelliJ IDEA इस चेतावनी के संदर्भ मेनू में इस अक्षम टिप्पणी को जोड़ने की पेशकश नहीं करता है।
अल्फ

मैं इस PyCharm निरीक्षण की गंभीरता को "चेतावनी" से "नो हाइलाइटिंग, केवल फिक्स" से PyCharm की प्राथमिकताओं में बदलने का सुझाव देता हूं। (यह मेरे लिए कई झूठी सकारात्मकता पैदा कर रहा है।)
मकीक

51

@Jolvi, @ArundasR, और अन्य लोगों से सहमत, चेतावनी एक सदस्य फ़ंक्शन पर होती है जो उपयोग नहीं करता है self

यदि आप सुनिश्चित हैं कि PyCharm गलत है, तो फ़ंक्शन एक नहीं होना चाहिए @staticmethod, और यदि आप शून्य चेतावनियों को महत्व देते हैं, तो आप इसे दो अलग-अलग तरीकों से दूर कर सकते हैं:

वर्कअराउंड # 1

def bar(self):
    self.is_not_used()
    doing_something_without_self()

def is_not_used(self):
    pass

समाधान # 2 [धन्यवाद @ डेविडसन ]

# noinspection PyMethodMayBeStatic
def bar(self):
    doing_something_without_self()

मेरे पास इसके लिए आवेदन (कारण मैं @staticmethod का उपयोग नहीं कर सका) एक प्रोटोकॉल उपप्रकार क्षेत्र का जवाब देने के लिए हैंडलर फ़ंक्शन की एक तालिका बनाने में था। सभी संचालकों को समान रूप से पाठ्यक्रम (स्थिर या गैर-स्थिर) होना चाहिए था। लेकिन कुछ उदाहरण के साथ कुछ भी करने के लिए नहीं हुआ। अगर मैंने उन स्थैतिक को बनाया, तो मुझे "TypeError: 'staticmethod' ऑब्जेक्ट कॉल करने योग्य नहीं है"।

ओपी की अड़चन के समर्थन में, आपको सुझाव है कि जब भी आप कर सकते हैं, स्टेथमेथोड को जोड़ दें, इस सिद्धांत के खिलाफ जाता है कि कोड को बाद में कम प्रतिबंधक बनाना आसान है, इसे और अधिक बनाने के लिए - एक विधि को स्थिर बनाने से यह अब कम प्रतिबंधात्मक हो जाता है, इसमें आप कॉल class.f () के बजाय example.f () करें।

लगता है कि क्यों यह चेतावनी मौजूद है:

  • यह staticmethod का विज्ञापन करता है । यह डेवलपर्स को कुछ ऐसी चीज़ों से अवगत कराता है जो उन्होंने अच्छी तरह से इरादा किया हो।
  • जैसा कि @ JohnWorrall बताते हैं, जब आपका ध्यान इस पर जाता है स्वयं अनजाने में फ़ंक्शन से बाहर निकल जाता था
  • यह ऑब्जेक्ट मॉडल पर पुनर्विचार करने के लिए एक क्यू है; हो सकता है कि फ़ंक्शन इस वर्ग में बिल्कुल न हो।

1
"एक विधि को स्थिर बनाने से यह अब कम प्रतिबंधात्मक हो जाता है" --- यह बिल्कुल नहीं है। जैसे: बहुरूपी विधियाँ
३:१५ बजे

मुझे लगता है कि अंतिम बिंदु दोहराता है: "जब आप स्पष्ट रूप से कार्य करते हैं तो आप इसे एक विधि क्यों बनाते हैं?" सामान को रखें जो वास्तव में संरचनात्मक पहलू से अलग एक उदाहरण की आवश्यकता है जो किसी पहलू से संबंधित है। फिर आप इसे अलग मॉड्यूल में आसानी से उप-विभाजित कर सकते हैं।
ढिल्लों

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

7
# noinspection PyMethodMayBeStaticविधि या वर्ग के ऊपर जोड़ने से चेतावनी दब जाती है, और मेरी राय में खाली पद्धति को कॉल करने से बेहतर है।
डेविड पियर्सन

1
@ ताल: पायथन 3 selfमें बिल्कुल नहीं हटाया गया है।
जुनेक्स

12

मुझे लगता है कि इस चेतावनी का कारण Pycharm में विन्यास है। आप चयन को अनचेक कर सकते हैं विधि संपादक-> निरीक्षण में स्थिर हो सकती है


12
मेरा सवाल था कि ऐसा निरीक्षण क्यों मौजूद था। मैं समझता हूं कि मैं इसे बंद कर सकता हूं। क्षमा करें, उत्तर नहीं।
२२:०६ पर

9

मैं यहां दिए गए उत्तरों से सहमत हूं (विधि का उपयोग नहीं selfकिया जाता है और इसलिए इसे सजाया जा सकता है @staticmethod)।

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

विधि को शीर्ष-स्तरीय फ़ंक्शन पर ले जाने से PyCharm चेतावनी भी ठीक हो जाएगी।


वास्तव में उपयोगी उत्तर - शायद पार्मार्म को चेतावनी का नाम बदलकर 'विधि स्थिर या शीर्ष-स्तरीय कार्य' हो सकता है। जब एक विधि को बाहर निकालते हैं, तो pycharm एक शीर्ष-स्तरीय फ़ंक्शन बनाएगा और एक स्थिर विधि नहीं होगी, अगर selfकोई पैरामीटर नहीं है।
सुजाना १

डेकोरेटर का उल्लेख करने के लिए @tlo +1। मेरे पास एक ऐसी विधि है जिसका उपयोग नहीं किया जाता है selfऔर इसलिए शीर्ष-स्तर हो सकता है, हालांकि, यह तार्किक नहीं लगता है कि यह विधि क्या करती है - शीर्ष स्तर के रूप में यह एक वैश्विक पद्धति की तरह दिखती है, जबकि यह है वास्तव में उस वर्ग से निर्मित उदाहरणों के लिए एक छोटी सहायक विधि। इसलिए मेरे कोड को तार्किक रूप से व्यवस्थित रखने के लिए, डेकोरेटर सही समाधान है।
कासिमिर

7

मैं एक स्थिर के रूप में परिभाषित एक वर्ग विधि होने के निम्नलिखित लाभों की कल्पना कर सकता हूं:

  • आप विधि को केवल कक्षा के नाम का उपयोग करके कॉल कर सकते हैं, इसे तुरंत करने की आवश्यकता नहीं है।

शेष लाभ शायद सीमांत हैं यदि सभी में मौजूद हैं:

  • थोड़ा तेज दौड़ सकते हैं
  • थोड़ी याददाश्त बचाओ

हां। लेकिन बात यह है - मैं इसे एक स्थिर विधि के रूप में उपयोग नहीं कर रहा हूं। अन्यथा यह पहले से ही स्थिर होगा। तो PyCharm इसे बिना किसी अच्छे कारण (?) के साथ करने की सलाह देता है। "शेष लाभ शायद सीमांत हैं यदि सभी में मौजूद हैं" --- हां, बिल्कुल। लेकिन अगर यह मामला है - यह PyCharm से एक मूर्खतापूर्ण सलाह है
झटके

1
@ इस तरह से यह कुछ आकर्षक उदाहरणों के साथ चला जाता है :-)
Jan Vlcinsky

2
अच्छा सॉफ्टवेयर बनाने के लिए स्टैटिक तरीके दुश्मन हैं। वे कई सिद्धांतों को शून्य करते हैं, इसलिए bitतेजी से दौड़ना बिंदु नहीं है (क्योंकि वे दोनों मामलों में इसके तेज में चलते हैं) और जैसा कि आप जानते हैं कि कंप्यूटर में अब bunchमेमोरी है, इसलिए अब कोई समस्या नहीं है। अपने पहले विचार पर भी ध्यान दें: यह एक प्रक्रियात्मक व्यवहार है न कि एक वस्तु उन्मुख।
अमीरहोसिन

4

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

संक्षेप में, मुझे शत-प्रतिशत यकीन नहीं है कि ऐसा क्यों है। मुझे लगता है कि वे शायद इसे आगामी रिलीज में हटा देंगे।


3

इस त्रुटि संदेश ने मुझे एक गुच्छा देने में मदद की, क्योंकि मुझे एहसास नहीं था कि मैंने गलती से अपने परीक्षण उदाहरण खिलाड़ी का उपयोग करके अपना फ़ंक्शन लिखा था

my_player.attributes[item] 

सही तरीके के बजाय

self.attributes[item]

1

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

यदि आपकी विधि में केवल साइड इफेक्ट्स हैं और आप इस बात की परवाह नहीं करते हैं कि यह क्या देता है:

def bar(self):
    doing_something_without_self()
    return self

यदि आपको रिटर्न वैल्यू की आवश्यकता है:

def bar(self):
    result = doing_something_without_self()
    if self:
        return result

अब आपकी विधि का उपयोग किया जा रहा है self, और चेतावनी दूर हो जाती है!


0

यही कारण है कि पाइक्रोम इसे एक चेतावनी के रूप में बनाते हैं क्योंकि पायथन पहले तर्क के रूप में स्वयं को पारित कर देगा जब कोई भी स्थिर विधि (@staticmethod नहीं जोड़ें)। Pycharm यह जानता है।

उदाहरण:

class T:
    def test():
        print "i am a normal method!"

t = T()
t.test()
output:
Traceback (most recent call last):
  File "F:/Workspace/test_script/test.py", line 28, in <module>
    T().test()
TypeError: test() takes no arguments (1 given)

मैं जावा से हूं, जावा में "सेल्फ" को "यह" कहा जाता है, आपको क्लास विधि में तर्क के रूप में स्वयं (या यह) लिखने की आवश्यकता नहीं है। आप बस स्वयं को कॉल कर सकते हैं जैसा कि आपको विधि के अंदर की आवश्यकता है। लेकिन पायथन "को स्वयं को एक विधि तर्क के रूप में पारित करना होगा।"

इसे समझकर आपको @BobStein जवाब के रूप में किसी भी वर्कअराउंड की आवश्यकता नहीं है।


यह selfतो गुजरता है क्या?
झटके

@zerkms '@staticmethod' 'स्व' पास नहीं करता
Junyu Wu

मैंने सिर्फ आपको उद्धृत किया: "पायथन स्वयं को पहले तर्क के रूप में पारित करेगा ... पाइक्रोम यह जानता है।" तो क्या? Pycharm यह जानता है, मैं यह जानता हूँ। विधि को चिह्नित करने का क्या कारण है?
१४:१४

@ अक्षरा क्योंकि पिच्चर को लगता है कि आपका पहला तरीका परम "स्व" नहीं हो सकता है। आम तौर पर पीपीएल एक विधि परम को डिजाइन नहीं करेगा और इसका उपयोग कभी नहीं करेगा। Pycharm को लगता है कि आप एक स्थिर विधि बना रहे हैं और यह महसूस नहीं किया कि पहला परम "स्वयं" नहीं है, इसलिए यह डिफ़ॉल्ट रूप से चेतावनी देता है। यह भ्रम प्रोग्रामिंग भाषा डिज़ाइन के कारण होता है। मेरा सुझाव है कि आप प्रोग्रामिंग डिजाइन का पालन करें (यहां तक ​​कि यह एक अच्छा पैटर्न नहीं लगता है), भ्रम से बचने के लिए, "स्टेटमिथोड" जोड़ें। यह पूरी तरह से ठीक है यदि आप "स्व" जोड़ते हैं तो यदि आप चाहें तो इसका उपयोग कभी न करें। जो मैं कहता हूं वह प्रोग्रामिंग डिज़ाइन को समझकर सिर्फ एक अलग विकल्प है।
जुएन वू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.