Converting a varargs tuple to a list - a definite pitfall for new comers to Python

M

metaperl.etc

The following program does not work if you uncomment #lis =
["xmms2"] + list(args)

Evidently Python is opting for the nullary constructor list() as
opposed to the other one which takes a sequence. But no newcomer would
know this. And the Python docs dont give a good example of dealing with
taking a sequence of args and converting it to a list.

I must've spent 40 minutes looking through my ora books, googling and
irc'ing in vane on this.

import subprocess

def xmms2(*args):
#lis = ["xmms2"] + list(args)
lis = ["xmms2"] + [a for a in args]
output = subprocess.Popen(lis,
stdout=subprocess.PIPE).communicate()[0]
return output.splitlines()

def list():
lis = xmms2('list')
playtime_str = lis.pop()
(total, playtime, time_str) = playtime_str.split()
(h,m,s) = time_str.split(':')
lis.pop()
return dict( playlist = lis, playtime = (int(h), int(m), int(s)) )

if __name__ == '__main__':
list()
 
S

Simon Forman

The following program does not work if you uncomment #lis =
["xmms2"] + list(args)

Evidently Python is opting for the nullary constructor list() as
opposed to the other one which takes a sequence. But no newcomer would
know this. And the Python docs dont give a good example of dealing with
taking a sequence of args and converting it to a list.

I must've spent 40 minutes looking through my ora books, googling and
irc'ing in vane on this.

import subprocess

def xmms2(*args):
#lis = ["xmms2"] + list(args)
lis = ["xmms2"] + [a for a in args]
output = subprocess.Popen(lis,
stdout=subprocess.PIPE).communicate()[0]
return output.splitlines()

def list():
lis = xmms2('list')
playtime_str = lis.pop()
(total, playtime, time_str) = playtime_str.split()
(h,m,s) = time_str.split(':')
lis.pop()
return dict( playlist = lis, playtime = (int(h), int(m), int(s)) )

if __name__ == '__main__':
list()


|>> def xmms2(*args):
.... lis = ["xmms2"] + list(args)
.... return lis
....
|>> xmms2('list')
['xmms2', 'list']
|>>
|>> xmms2('list', 'bananas', 'apples')
['xmms2', 'list', 'bananas', 'apples']


It must be something else?

Also, "nullary"?
 
G

Georg Brandl

The following program does not work if you uncomment #lis =
["xmms2"] + list(args)

Evidently Python is opting for the nullary constructor list() as
opposed to the other one which takes a sequence. But no newcomer would
know this. And the Python docs dont give a good example of dealing with
taking a sequence of args and converting it to a list.

Evidently you overlooked having defined a list() in global scope
yourself which takes no arguments.
I must've spent 40 minutes looking through my ora books, googling and
irc'ing in vane on this.

import subprocess

def xmms2(*args):
#lis = ["xmms2"] + list(args)
lis = ["xmms2"] + [a for a in args]
output = subprocess.Popen(lis,
stdout=subprocess.PIPE).communicate()[0]
return output.splitlines()

def list():
^^^^^^^^^^^

This is called by list(args) above, and the call fails.
If you want to avoid such clashes, don't name your functions list,
dict, int, str etc.

Georg
 
J

John Machin

The following program does not work if you uncomment #lis =
["xmms2"] + list(args)

Evidently Python is opting for the nullary constructor list() as
opposed to the other one which takes a sequence. But no newcomer would know this.

Are you using "the nullary constructor list()" to mean "the 0-argument
function list() that appears later in the script", and "the other one
which takes a sequence" to mean the builtin function list()"??? If, so
I guess it's not just newcomers to the English language who would be
struggling to comprehend :)
And the Python docs dont give a good example of dealing with
taking a sequence of args and converting it to a list.

You have produced 2 perfectly good examples yourself. What's your
point?
I must've spent 40 minutes looking through my ora books, googling and
irc'ing in vane on this.

There is nothing at all special about a sequence of args. It's just a
tuple, as documented and discoverable:

| >>> def func(*args):
| ... print type(args), repr(args)
| ...
| >>> func(1,2,3,4)
| <type 'tuple'> (1, 2, 3, 4)
| >>>

Here's a tip: when you get into a pickle like that, try running
pychecker and/or pylint over your code. Here's what pychecker has to
say:

metaperllist.py:4: Invalid arguments to (list), got 1, expected 0
metaperllist.py:10: (list) shadows builtin

HTH,
John
 
M

metaperl

Georg said:
The following program does not work if you uncomment #lis =
["xmms2"] + list(args)

Evidently Python is opting for the nullary constructor list() as
opposed to the other one which takes a sequence. But no newcomer would
know this. And the Python docs dont give a good example of dealing with
taking a sequence of args and converting it to a list.

Evidently you overlooked having defined a list() in global scope
yourself which takes no arguments.

MASSIVELY overlooked it. Gosh. How embarrassing.
 
M

metaperl

John said:
The following program does not work if you uncomment #lis =
["xmms2"] + list(args)

Evidently Python is opting for the nullary constructor list() as
opposed to the other one which takes a sequence. But no newcomer would know this.

Are you using "the nullary constructor list()" to mean "the 0-argument
function list() that appears later in the script", and "the other one
which takes a sequence" to mean the builtin function list()"???

No, I'm talking about listing 2 here:
http://www-128.ibm.com/developerworks/library/os-python4/index.html

which states:
"If you look closely at the description for the list class in Listing
2, you'll see that two different constructors are provided. One takes
no arguments, and the other takes a sequence class."

and I figured that since the lower bound on arguments to *args could
zero, that Python was
default to the nullary constructor even before the function got its
args.

paranoia will do these things to you.

You have produced 2 perfectly good examples yourself. What's your
point?

I just mean that this:
http://docs.python.org/tut/node6.html#SECTION006730000000000000000

does not use list() at all.


Here's a tip: when you get into a pickle like that, try running
pychecker and/or pylint over your code. Here's what pychecker has to
say:

metaperllist.py:4: Invalid arguments to (list), got 1, expected 0
metaperllist.py:10: (list) shadows builtin


Great suggestion. I had not heard of those. Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top