2011-10-13 11 views
6

私の選択したテキストエディタは、Pythonプラグインによって拡張可能です。クラスを拡張してメソッドをオーバーライドする必要があります。一般的な構造は以下のスニペットに似ています。関数の署名は固定されていることに注意してください。クラス外の可変スコープ

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() # 

これらのクラスには、共通の変数が1つあります。変数を共有するためのベストプラクティスは何ですか? madjarsに基づい

編集は答える:

FtpFileCommand.runが最初に呼び出され、ftp_clientをinstanciatesと魔法のように動作します。 FtpFileEventListener.runは後で呼び出され、ftp_clientを完全に参照できますが、まだNoneです。グローバルキーワードを使用して、変数をメンバーとしてselfに追加しますか?

+0

編集で2番目の質問に答えるには: 'ftp_client'をインスタンス属性にすると、グローバルを使う目的が無効になります。新しい 'FTP'オブジェクトは、グローバルとして最初に宣言した後、' ftp_client'変数に代入されるべきです。その後、それをグローバルとして宣言する必要なしにどこからでも参照することができます。 'ftp_client.quit()' – ekhumoro

答えて

5

これはまさにglobalの動作です。

これはPython標準ライブラリ(たとえば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

Xavier Combelle:私の投稿に与えられた構造は固定されており、コンストラクタをオーバーライドすることはできません。 – fjdumont

3

共有変数が1つしかない場合は、グローバル変数が最も簡単なソリューションです。しかし、変数が代入されるときには、変数はglobalと宣言する必要があるだけであることに注意してください。グローバル変数がオブジェクトの場合は、そのメソッドをグローバルに宣言することなくそのメソッドを呼び出したり、その属性を変更したりすることができます。

グローバル変数を使用する代わりに、classmethodsを使用してアクセスするクラス属性を使用することもできます。このコードで

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

今それはスマートな解決策です!代入中に 'global'が必要なことを明確にしてくれてありがとう。私はちょうどあなたの答えを+1しました。なぜなら、madjarsの答えからソリューションマークを削除するのがいたずらに感じるからです... – fjdumont

4

:たとえば

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

あなたはグローバル変数としてftp_clientを宣言する。これは、モジュールレベル(クラスがある場所など)に存在することを意味します。

2行目が間違っています。グローバル変数に代入したいのではなく、同じ名前のインスタンス属性を設定しました。

それは次のようになります。

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 

クラス名を使用せずにFTPクライアントにアクセスします。

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() 

。私はPythonの初心者で、しばらくの間これに苦労しました。私は別の.pyファイルで構成されたカスタムモジュールを用意しました。 mainはmoduleAを呼び出し、moduleAはmoduleBを呼び出していました。変数をチェーンのメインスクリプトに戻さなければなりませんでした。私がこのようにしているのは、主なスクリプトを大部分はきれいにしておき、繰り返しのタスクを実行するために自分自身を設定して、クラップスのページを書く必要がないようにすることでした。基本的には、本を書く代わりに関数を再利用しようとしています。