2011-10-13 15 views
6

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

ftp_client दोनों वर्गों के उदाहरणों द्वारा साझा किया जाना चाहिए।

ftp_client = None 

class FtpFileCommand(sublime_plugin.TextCommand): 
    def run(self, args): 
    global ftp_client # does it reference the variable of the outer scope? 
    self.ftp_client = ftplib.FTP('foo') 
    # login and stuff 

class FtpFileEventListener(sublime_plugin.EventListener): 
    def run(self, args): 
    global ftp_client # same for this 
    self.ftp_client.quit() # 

इन दोनों कक्षाओं में एक चर सामान्य है। चर साझा करने के लिए सबसे अच्छा अभ्यास क्या है?

संपादित madjars के आधार पर उत्तर दें:

FtpFileCommand.run पहले कहा जाता है, ftp_client instanciates और एक आकर्षण की तरह काम करता है। FtpFileEventListener.run को बाद में बुलाया जाता है और, ftp_client पूरी तरह से संदर्भित कर सकता है लेकिन यह अभी भी None है। वैश्विक कीवर्ड का उपयोग करके, क्या यह चर को सदस्य के रूप में self में जोड़ता है?

+0

आपके संपादन में दूसरे प्रश्न का उत्तर देने के लिए: 'ftp_client' बनाना एक आवृत्ति विशेषता ग्लोबल्स का उपयोग करने के उद्देश्य को हरा देती है। नया 'एफ़टीपी' ऑब्जेक्ट इसे वैश्विक रूप में घोषित करने के बाद 'ftp_client' चर को असाइन किया जाना चाहिए। इसके बाद, इसे वैश्विक रूप से घोषित करने की आवश्यकता के बिना कहीं से भी संदर्भित किया जा सकता है, उदा। 'Ftp_client.quit()'। – ekhumoro

उत्तर

5

हाँ, यह ठीक है कि global काम करता है।

ऐसा लगता है कि आप इसे सही कर रहे हैं, क्योंकि यह पाइथन मानक पुस्तकालय (fileinput, उदाहरण के लिए) के कुछ मॉड्यूल में ऐसा किया गया है।

+1

मैंने आपके उत्तर के आधार पर प्रश्न संपादित किया है, कृपया एक नज़र डालें :) – fjdumont

+1

'वैश्विक ftp_client' करने के बाद, आप इसे 'ftp_client' का उपयोग करके एक्सेस कर सकते हैं। सावधान रहें, क्योंकि 'self.ftp_client' उदाहरण की विशेषता को संदर्भित करेगा, जो वैश्विक' ftp_client' से अलग है। – madjar

+0

इसे तुरंत उत्तर देने के लिए धन्यवाद। ईमानदारी से, दस्तावेज़ों की पुन: खोज से मुझे भी मदद मिली हो सकती है। आलसी मुझे ... – fjdumont

0

क्या आप प्रत्येक कक्षा में एक कन्स्ट्रक्टर जोड़ सकते हैं और ftp_client को तर्क के रूप में पास कर सकते हैं?

class FtpFileCommand(sublime_plugin.TextCommand): 
    ... 
    def __init__(self, ftp_client): 
     self.ftp_client = ftp_client 
    ... 

class FtpFileEventListener(sublime_plugin.EventListener): 
    ... 
    def __init__(self, ftp_client): 
     self.ftp_client = ftp_client 
    ... 
+0

मुझे डर है कि प्लगइन सिस्टम प्लगइन्स को pzarameters स्वीकार नहीं कर सकता –

+0

जेवियर कॉम्बल: बिल्कुल, मेरी पोस्ट में दी गई संरचना तय की गई है और मुझे रचनाकारों को ओवरराइड करने की अनुमति नहीं है। – fjdumont

3

यदि केवल एक साझा साझा चर है, तो वैश्विक एक सरल समाधान है। लेकिन ध्यान दें कि एक चर को केवल global के साथ घोषित किया जाना चाहिए जब इसे असाइन किया जा रहा हो। यदि वैश्विक चर एक वस्तु है, तो आप इसकी विधियों को कॉल कर सकते हैं, इसके गुणों को संशोधित कर सकते हैं, आदि इसे वैश्विक रूप में घोषित किए बिना।

वैश्विक चर का उपयोग करने का एक विकल्प क्लास गुणों का उपयोग करना है जो क्लासमेड का उपयोग करके एक्सेस किया जाता है।

class FtpFile(object): 
    _client = None 

    @classmethod 
    def client(cls): 
     return cls._client 

    @classmethod 
    def setClient(cls, client): 
     cls._client = client 

class FtpFileCommand(FtpFile, sublime_plugin.TextCommand): 
    def run(self, args): 
     client = self.client() 

class FtpFileEventListener(FtpFile, sublime_plugin.EventListener): 
    def run(self, args): 
     client = self.client() 
+0

अब यह एक स्मार्ट समाधान है! यह स्पष्ट करने के लिए धन्यवाद कि 'वैश्विक' केवल असाइनमेंट के दौरान आवश्यक है। मैंने अभी आपका जवाब +1 किया क्योंकि मुझे पागल जवाब से समाधान चिह्न को हटाने में शरारती महसूस होती है ... – fjdumont

4

इस कोड में: उदाहरण के लिए:

global ftp_client # does it reference the variable of the outer scope? 
self.ftp_client = ftplib.FTP('foo') 

आप एक वैश्विक चर के रूप में ftp_client घोषणा करते हैं। इसका मतलब है कि यह मॉड्यूल स्तर पर रहता है (जहां आपकी कक्षाएं उदाहरण के लिए हैं)।

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

यह होना चाहिए:

global ftp_client 
ftp_client = ftplib.FTP('foo') 

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

class FtpFileCommand(sublime_plugin.TextCommand): 
    ftp_client = None 

    def run(self, args): 
    FtpFileCommand.ftp_client = ftplib.FTP('foo') 
    # login and stuff 

सूचना है कि विधि self उपयोग नहीं करता है तो यह रूप में अच्छी तरह से एक वर्ग विधि हो सकती है:

class FtpFileCommand(sublime_plugin.TextCommand): 
    ftp_client = None 

    @classmethod 
    def run(cls, args): 
    cls.ftp_client = ftplib.FTP('foo') 
    # login and stuff 

इस तरह से आप पहले तर्क के रूप में वर्ग मिल जाएगा और आप के लिए इसका इस्तेमाल कर सकते हैं क्लास नाम का उपयोग किए बिना एफ़टीपी क्लाइंट तक पहुंचें।

0

याक ... आपको इसके लिए बहुत कुछ धन्यवाद !!!

आप वैश्विक चर के रूप में ftp_client घोषित करते हैं। इसका मतलब है कि यह मॉड्यूल स्तर पर रहता है (जहां आपकी कक्षाएं उदाहरण के लिए हैं)।

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

module.variable 

और फिर कि मॉड्यूल के भीतर , मैं एक वैश्विक चर यह मुख्य स्क्रिप्ट ... तो उदाहरण से कॉल करने के लिए की घोषणा की ...

#Main Script main.py 
import moduleA 

print(moduleA.moduleA.variable) 


#ModuleA code moduleA.py 
import moduleB 

class classA(): 

    def functionA(): 

     global moduleA_variable 
     call.something.from.moduleB.classB.functionB() 
     moduleA_variable = moduleB.moduleB_variable 

ModuleB कोड moduleB.py

class classB(): 

    def functionB(): 

     global moduleB_variable 
     moduleB_variable = retrieve.tacos() 

मुझे आशा है कि मेरी व्याख्या भी कोई मदद करता है। मैं अजगर के साथ एक नौसिखिया हूँ और थोड़ी देर के लिए इसके साथ संघर्ष किया। अगर यह स्पष्ट नहीं था ... मेरे पास कुछ अलग .py फाइलों से बने अलग-अलग कस्टम मॉड्यूल थे। मुख्य मॉड्यूल को कॉल कर रहा था और मॉड्यूलए मॉड्यूल बी को कॉल कर रहा था। मुझे श्रृंखला को मुख्य लिपि में चर को वापस करना पड़ा। मुझे इस तरह से करने का मुद्दा मुख्य स्क्रिप्ट को अधिकांश भाग के लिए साफ रखना था, और बकवास के पृष्ठों को लिखने के बिना दोहराए गए कार्यों को निष्पादित करने के लिए खुद को स्थापित करना था। मूल रूप से एक पुस्तक लिखने के बजाय कार्यों का पुन: उपयोग करने की कोशिश कर रहा है।

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