STR that should be file?

Alex Martelli aleax at aleax.it
Tue Mar 25 13:12:46 CET 2003


j2 wrote:

> Ok, as my code clearly demonstrates, i am a blatant newbie.. but i cant
> figure this out. Traceback at the bottom (Python 2.2 on win32)  Help?
   ...
> # This will handle the data being downloaded
> # It will be explained shortly
> def handleDownload(block):
>     file.write(block)
>     print ".",

file is the name of a built-in type (the type of file objects).  So,
file.write is an unbound method of the type, which needs to be called
with an instance of the type as its first argument -- and the first
argument you're using is 'block', a string, whence the traceback.

You're using name 'file' for a local variable in the following
function getFile (don't do that -- it's NOT a good idea to name
your own variables with names of builtin types!), but that does
not in the least affect function handleDownload.

Since the callback you want to use must have both state (a file
object) AND behavior (code), a simple function is not suitable:
you need either a closure or the instance of a class.  With a
closure:

def makeDownloader(somefile):
    def handleDownload(block):
        somefile.write(block)
        print ',',
    return handleDownload

or with a class:

class Downloader:
    def __init__(self, somefile):
        self.somefile = somefile
    def __call__(self, block):
        somefile.write(block)
        print ',',

and in the function getFile to use either of these approaches
you need one small change, to wit:


> #COde to fetch a file, and write it to disk
> def getFile(Path, Name, Destination):
>     ftp = FTP(ftpsite)
>     try:
>         print ftp.login()
>     except:
>         print "Unable to log on to FTP"
>         sys.exit(1)
>     try:
>         print 'Changing to ' + Path
>         ftp.cwd(Path)
>     except:
>         print "Unable to CWD"
>         sys.exit(5)
>     #Try fetiching the file
>     print "Saving file to " + tempdir + Destination
>     file = open(tempdir + Destination, 'wb')

change this to, e.g.,

      myfile = open(tempdir + Destination, 'wb')

or whatever, but don't use name 'file' -- just advice!


>     print "Getting " + Name

insert here, either:
      handleDownload = makeDownloader(myfile)
or:
      handleDownload = Downloader(myfile)

>     ftp.retrbinary('RETR ' + Path + Name , handleDownload)
>     print 'Closing file ' + Name
>     file.close()

this needs to become:
      myfile.close()
to match the variable name change above suggested.

>     ftp.close()
> 
> getFile(directory,'update.ini','update.ini')


Alex





More information about the Python-list mailing list