Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Increment variable in callback during upload

I have the following python script for an upload that needs to show percent done. I am having trouble incrementing the variable that tracks the amount of data transferred. I get an
UnboundLocalError: local variable 'intProgress' referenced before assignment
error. Yet if I try to print this variable it prints fine so it seems that it is referenced.

import os, sys, ftplib
pathname = 'C:/Paradigm1/1.PNG'
intFileSize = os.path.getsize(pathname)
intPercentDone = 0
intProgress = 0

def callback(p):
    intProgress = intProgress + 1024
    ##sys.stdout.write(str(intProgress))
    sys.stdout.write("-")
session = ftplib.FTP('Server','UserName','Password')
f = open(pathname,'rb')# file to send
session.storbinary('STOR /Ftp Accounts/PublicDownloads/test.png', f, 1024, callback)
f.close()
like image 374
HelloW Avatar asked Jun 07 '13 16:06

HelloW


2 Answers

If you want the callback() function to change the global variable intProgress, you have to declare it as global in the function...

def callback(p):
    global intProgress
    intProgress = intProgress + 1024
    ##sys.stdout.write(str(intProgress))
    sys.stdout.write("-")

...otherwise it'll assume intProgress is a local variable, and get confused by the fact that you're trying to reference it when setting it.

like image 171
Aya Avatar answered Nov 05 '22 14:11

Aya


intProgress = inside a function forces Python to treat it as a local variable overshadowing the variable from the outer scope.

To avoid mutable globals, you could create a closure:

import os
import sys

def make_callback(filesize):
    total = [0] # use list to emulate nonlocal keyword
    width = len(str(filesize))

    def report_progress(block):
        total[0] += len(block)
        sys.stderr.write("\r{:{}d} / {}".format(total[0], width, filesize))

    return report_progress

def main():
    # ...
    ftp.storbinary(..., make_callback(os.path.getsize(filename)))

main()
like image 34
jfs Avatar answered Nov 05 '22 14:11

jfs