args v. *args passed to: os.path.join()
Heiko Wundram
heikowu at ceosg.de
Sat Sep 18 14:08:35 EDT 2004
Before applying args or *args to a real world sample, lets see what each of
them does:
>>> def testfunc(*args):
... print args
...
Define a function called testfunc, for which all positional arguments are
stored to the tuple args. The body of this functions contains a single
statement which prints this tuple to screen.
>>> testfunc([1,2,3])
([1, 2, 3],)
The tuple which is printed to screen is the following: a tuple with a single
item which is a list which contains the elements 1, 2 and 3 in this order.
>>> testfunc(*[1,2,3])
(1, 2, 3)
The tuple which is printed to screen is the following: a tuple with the items
1, 2 and 3 in this order.
See where we're heading at? Let's see another example.
>>> def testfunc2(a,b):
... print a
... print b
...
Lets define another function which takes two arguments (a, b) and prints them
out in order.
>>> testfunc2([1,2])
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: testfunc2() takes exactly 2 arguments (1 given)
Lets call this function with a single argument (a list, which contains the two
items). The interpreter duly complains that the function takes two arguments,
but only one is given, and raises a TypeError.
>>> testfunc2(*[1,2])
1
2
Again, using the star syntax: We pass two arguments (because the list which is
starred contains two arguments), and these end up in a and b, respectively.
So, what does the star-operator do? It splits up an iterable (a list in this
case) and fills the first len(iterable) positional arguments with the values
it got from the list.
This is why you see different behavior when passing a star or not. Let's look
at the documentation for os.path.join:
join(a, *p)
Join two or more pathname components, inserting '/' as needed
This means that you have to pass at least one argument (a), which is the path
base, and may pass more arguments (*p) which are joined with this item,
inserting slashes as needed.
Now, when you call:
os.path.join(["a","b"])
the list ends up in the a parameter, and because the function doesn't have to
do anything (there are no more arguments), the list is returned unchanged
(although this should probably raise a TypeError, anyone?).
But when you call:
os.path.join(*["a","b"])
the first item of the list ends up as parameter a to the function, the second
item of the list ends up as the second parameter to the function, which are
then duly joined by the function.
And one more look why "".join(*["a","b"]) raises an error:
join(...)
S.join(sequence) -> string
Return a string which is the concatenation of the strings in the
sequence. The separator between elements is S.
The documentation for str.join() states that you pass it one parameter, a
sequence.
Now, when you do "".join(*["a","b"]), the number of passed parameters is two,
and because the function only accepts one parameter, a sequence, the function
call raises an Exception.
HTH!
Heiko.
More information about the Python-list
mailing list