Question

Well, when you assign something to a variable in Python:

a = 1

nothing visible happens, nothing is printed out.

But in this case:

import ftplib
ftp = ftplib.FTP("igscb.jpl.nasa.gov")
ftp.login()
a=ftp.retrlines('LIST')

When the last line is executed, this is printed out:

d--X--X--X--X 2 0      0     4096 Nov 29 2001 bin
d--X--X--X--X 2 0      0     4096 Nov 29 2001 etc

which is the information related to the FTP directory.

How comes that a variable assignment yields an output?

Was it helpful?

Solution 3

See the source code: http://hg.python.org/cpython/file/2.7/Lib/ftplib.py

   418 def retrlines(self, cmd, callback = None):
   419     """Retrieve data in line mode.  A new port is created for you.
   420 
   421     Args:
   422       cmd: A RETR, LIST, NLST, or MLSD command.
   423       callback: An optional single parameter callable that is called
   424                 for each line with the trailing CRLF stripped.
   425                 [default: print_line()]
   426 
   427     Returns:
   428       The response code.
   429     """
   430     if callback is None: callback = print_line
   431     resp = self.sendcmd('TYPE A')
   432     conn = self.transfercmd(cmd)
   433     fp = conn.makefile('rb')
   434     while 1:
   435         line = fp.readline()
   436         if self.debugging > 2: print '*retr*', repr(line)
   437         if not line:
   438             break
   439         if line[-2:] == CRLF:
   440             line = line[:-2]
   441         elif line[-1:] == '\n':
   442             line = line[:-1]
   443         callback(line)
   444     fp.close()
   445     conn.close()
   446     return self.voidresp()

As other answers explain, the function retrlines() itself makes a call that prints to stdout. The relevant line is 430, where by default the variable callback is defined as the function print_line() which, not surprisingly, simply prints a given string:

   859 def print_line(line):
   860     '''Default retrlines callback to print a line.'''
   861     print line

The callback() function is called on line 443 of retrlines(), causing the line to be printed.

To suppress the print out, you can use retrlines() with a custom callback function that does not do anything, e.g.

ftp.retrlines('LIST', callback=lambda x: pass)

OTHER TIPS

May be because the function contains some prints statements, calling a function will always execute that function even if the return value is assigned to some variable.

Example:

>>> def func():
...     print "hello world"
...     return 'foo'
... 
>>> a = func()
hello world
>>> a
'foo'

Help on ftp.FTP.retrlines indicates that default callback calls print_line to print the data to sys.stdout.(From docs: The default callback prints the line to sys.stdout)

>>> from ftplib import FTP
>>> print FTP.retrlines.__doc__
Retrieve data in line mode.  A new port is created for you.

        Args:
          cmd: A RETR, LIST, NLST, or MLSD command.
          callback: An optional single parameter callable that is called
                    for each line with the trailing CRLF stripped.
                    [default: **print_line()**]

        Returns:
          The response code.

From the docs:

FTP.retrlines(command[, callback])

...

The callback function is called for each line with a string argument containing the line with the trailing CRLF stripped. The default callback prints the line to sys.stdout.

The function is printing the output. The assignment has nothing to do with it.

When you run

a=ftp.retrlines('LIST')

You are calling ftp.retrlines, which is a function that both returns a value (which gets stored in a), and writes to sys.stdout.

When you run

a = 1

You are just doing variable assignment, and the machinery that does variable assignment does not write to sys.stdout.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top