-1

ファイルを複数の IP アドレスにプッシュする単純なスクリプトを作成するために使用ftplibしています。これらはすべて FTP サーバーとして設定されています。ファイルのアップロード プロセスの進行状況を表示したかったのですが、問題が発生しています。のコールバック引数を使用すると、次のFTP.storbinary()ように機能します。

count = 0
def update(block):
   count2 = str(count + 1)
   print count2

ただし、呼び出しの外で演算を行おうとするstr()と、プログラムがハングします。したがって、以下は機能しません。

count = 0
def update(block):
   count += 1
   print count

呼び出しでラップcountしてstr()も機能しません。最初の呼び出しでハングするだけです。

4

2 に答える 2

1

ハングするだけでなく、例外 (具体的にはUnboundLocalError) を生成します。関数内でグローバル変数を変更しようとしています。これを行うには、変数を宣言する必要がありますglobal:

count = 0
def update(block):
   global count
   count += 1
   print count

これはほとんどの場合、設計が悪いことを示しています。あなたの場合は、おそらく属性を持つクラスを使用する方がよいでしょう:

class MyCallbackHandler(object):
    def __init__(self):
        self.count = 0

    def update(self, block):
        self.count += 1
        #... etc.
于 2013-08-05T22:34:53.137 に答える
1

updateに渡すのではなく、自分自身を呼び出してみるとFTP.storbinary、すぐに問題が発生します。

>>> update('')
UnboundLocalError: local variable 'count' referenced before assignment

グローバル変数を更新したい場合は、グローバル変数を明示的にマークする必要があります:

def update(block):
   global count
   count += 1
   print count

FAQ エントリを参照してください。変数に値があるのに UnboundLocalError が発生するのはなぜですか? および次の質問Python のローカル変数とグローバル変数のルールは何ですか? 、および のドキュメントでglobal詳細を確認してください。


これを解決するより良い方法は、クラスを書くことです:

class FtpHandler(object):
    def __init__(self):
        self.count = 0
    def update(self, block):
        self.count += 1
        print self.count

次に、それを使用するために、クラスのインスタンスを作成し、単純な関数の代わりにバインドされたメソッドを FTP コードに渡します。たとえば、これの代わりに:

ftp = ftplib.FTP(...)
# ...
ftp.storbinary(spam, eggs, callback=update)

… これを行う:

myhandler = FtpHandler()
ftp = ftplib.FTP(...)
# ...
ftp.storbinary(spam, eggs, callback=myhandler.update)
于 2013-08-05T22:34:34.943 に答える