os.path.join

Discussion in 'Python' started by Elliot Peele, May 2, 2007.

  1. Elliot Peele

    Elliot Peele Guest

    Why does os.path.join('/foo', '/bar') return '/bar' rather than
    '/foo/bar'? That just seems rather counter intuitive.

    Elliot
    Elliot Peele, May 2, 2007
    #1
    1. Advertising

  2. Elliot Peele

    7stud Guest

    On May 1, 7:36 pm, Elliot Peele <> wrote:
    > Why does os.path.join('/foo', '/bar') return '/bar' rather than
    > '/foo/bar'? That just seems rather counter intuitive.
    >
    > Elliot


    join( path1[, path2[, ...]])
    Join one or more path components intelligently. If any component is an
    absolute path, all previous components (on Windows, including the
    previous drive letter, if there was one) are thrown away...
    7stud, May 2, 2007
    #2
    1. Advertising

  3. Elliot Peele

    Elliot Peele Guest

    On Tue, 2007-05-01 at 19:27 -0700, 7stud wrote:
    > On May 1, 7:36 pm, Elliot Peele <> wrote:
    > > Why does os.path.join('/foo', '/bar') return '/bar' rather than
    > > '/foo/bar'? That just seems rather counter intuitive.
    > >
    > > Elliot

    >
    > join( path1[, path2[, ...]])
    > Join one or more path components intelligently. If any component is an
    > absolute path, all previous components (on Windows, including the
    > previous drive letter, if there was one) are thrown away...


    Yes, but that still doesn't answer my question as to why os.path.join
    works that way. I understand that that is how it is written, but why?

    Elliot
    Elliot Peele, May 2, 2007
    #3
  4. Elliot Peele

    Guest

    On May 1, 9:23 pm, Elliot Peele <> wrote:
    > On Tue, 2007-05-01 at 19:27 -0700, 7stud wrote:
    > > On May 1, 7:36 pm, Elliot Peele <> wrote:
    > > > Why does os.path.join('/foo', '/bar') return '/bar' rather than
    > > > '/foo/bar'? That just seems rather counter intuitive.

    >
    > > > Elliot

    >
    > > join( path1[, path2[, ...]])
    > > Join one or more path components intelligently. If any component is an
    > > absolute path, all previous components (on Windows, including the
    > > previous drive letter, if there was one) are thrown away...

    >
    > Yes, but that still doesn't answer my question as to why os.path.join
    > works that way. I understand that that is how it is written, but why?
    >
    > Elliot


    It makes perfect sense. You are joining two paths that both begin at
    the root directory. The second path is overwriting the first because
    they can't both begin at the root and also be parts of one path.

    A better question is why this doesn't work.

    >>> pathparts = ["/foo", "bar"]
    >>> os.path.join(pathparts)

    ['/foo', 'bar']

    This should return a string in my opinion.

    ~Sean
    , May 2, 2007
    #4
  5. En Wed, 02 May 2007 01:23:45 -0300, Elliot Peele <>
    escribió:

    > On Tue, 2007-05-01 at 19:27 -0700, 7stud wrote:
    >> On May 1, 7:36 pm, Elliot Peele <> wrote:
    >> > Why does os.path.join('/foo', '/bar') return '/bar' rather than
    >> > '/foo/bar'? That just seems rather counter intuitive.
    >> >
    >> > Elliot

    >>
    >> join( path1[, path2[, ...]])
    >> Join one or more path components intelligently. If any component is an
    >> absolute path, all previous components (on Windows, including the
    >> previous drive letter, if there was one) are thrown away...

    >
    > Yes, but that still doesn't answer my question as to why os.path.join
    > works that way. I understand that that is how it is written, but why?


    It's not *how* it is written, but the current documentation for
    os.path.join:
    http://docs.python.org/lib/module-os.path.html#l2h-2176
    It appears that the function docstring (used by the help system) is too
    terse here.

    --
    Gabriel Genellina
    Gabriel Genellina, May 2, 2007
    #5
  6. En Wed, 02 May 2007 02:31:43 -0300, <> escribió:

    > A better question is why this doesn't work.
    >
    >>>> pathparts = ["/foo", "bar"]
    >>>> os.path.join(pathparts)

    > ['/foo', 'bar']
    >
    > This should return a string in my opinion.


    I think it's a bug, but because it should raise TypeError instead.
    The right usage is os.path.join(*pathparts)

    --
    Gabriel Genellina
    Gabriel Genellina, May 2, 2007
    #6
  7. Elliot Peele

    Guest

    On May 1, 11:10 pm, "Gabriel Genellina" <>
    wrote:
    > En Wed, 02 May 2007 02:31:43 -0300, <> escribió:
    >
    > > A better question is why this doesn't work.

    >
    > >>>> pathparts = ["/foo", "bar"]
    > >>>> os.path.join(pathparts)

    > > ['/foo', 'bar']

    >
    > > This should return a string in my opinion.

    >
    > I think it's a bug, but because it should raise TypeError instead.
    > The right usage is os.path.join(*pathparts)
    >
    > --
    > Gabriel Genellina


    Wow. What exactly is that * operator doing? Is it only used in
    passing args to functions? Does it just expand the list into
    individual string arguments for exactly this situation? Or does it
    have other uses?

    ~Sean
    , May 2, 2007
    #7
  8. En Wed, 02 May 2007 04:03:56 -0300, <> escribió:

    > On May 1, 11:10 pm, "Gabriel Genellina" <>
    > wrote:


    >> The right usage is os.path.join(*pathparts)

    >
    > Wow. What exactly is that * operator doing? Is it only used in
    > passing args to functions? Does it just expand the list into
    > individual string arguments for exactly this situation? Or does it
    > have other uses?


    When calling a function, it is used to pass a sequence as positional
    arguments. Similarly, **values is used to pass a dictionary as keyword
    arguments.
    When defining a function, *args receives the remaining positional
    arguments not already bound to another parameter; and **kwargs receives
    the remaining keyword arguments not already bound to another parameter.
    [There is nothing special on the *args and **kwargs names, only the * and
    ** are important]
    See section 4.7 on the Python Tutorial
    http://docs.python.org/tut/node6.html#SECTION006700000000000000000 and
    specially section 4.7.4 Unpacking Argument Lists.
    For a more technical description (but sometimes necesary) read the Python
    Reference Manual http://docs.python.org/ref/calls.html

    --
    Gabriel Genellina
    Gabriel Genellina, May 2, 2007
    #8
  9. Elliot Peele

    Ant Guest

    On May 2, 8:03 am, wrote:
    > On May 1, 11:10 pm, "Gabriel Genellina" <>

    ....
    > > I think it's a bug, but because it should raise TypeError instead.
    > > The right usage is os.path.join(*pathparts)

    ....
    > Wow. What exactly is that * operator doing? Is it only used in
    > passing args to functions? Does it just expand the list into
    > individual string arguments for exactly this situation? Or does it
    > have other uses?


    It's used for unpacking a collection into arguments to a function.
    It's also used at the other end for receiving a variable length set of
    arguments. i.e.

    >>> x = (1,3)
    >>> def add(a, b):

    return a + b

    >>> add(*x)

    4
    >>> def add(*args):

    return reduce(int.__add__, args)

    >>> add(1,2,3,4,5,6)

    21
    >>> add(*x)

    4

    The same sort of thing holds for keyword arguments:

    >>> def print_kw(**kw):

    for k in kw:
    print kw[k]


    >>> print_kw(a=1, b=2)

    1
    2
    >>> d = {'a': 1, 'b': 10, 'c': 100}
    >>> print_kw(**d)

    1
    100
    10
    Ant, May 2, 2007
    #9
  10. Elliot Peele

    Guest

    On May 2, 12:36 am, Ant <> wrote:
    > On May 2, 8:03 am, wrote:
    >
    > > On May 1, 11:10 pm, "Gabriel Genellina" <>

    > ...
    > > > I think it's a bug, but because it should raise TypeError instead.
    > > > The right usage is os.path.join(*pathparts)

    > ...
    > > Wow. What exactly is that * operator doing? Is it only used in
    > > passing args to functions? Does it just expand the list into
    > > individual string arguments for exactly this situation? Or does it
    > > have other uses?

    >
    > It's used for unpacking a collection into arguments to a function.
    > It's also used at the other end for receiving a variable length set of
    > arguments. i.e.
    >
    > >>> x = (1,3)
    > >>> def add(a, b):

    >
    > return a + b
    >
    > >>> add(*x)

    > 4
    > >>> def add(*args):

    >
    > return reduce(int.__add__, args)
    >
    > >>> add(1,2,3,4,5,6)

    > 21
    > >>> add(*x)

    >
    > 4
    >
    > The same sort of thing holds for keyword arguments:
    >
    > >>> def print_kw(**kw):

    >
    > for k in kw:
    > print kw[k]
    >
    > >>> print_kw(a=1, b=2)

    >
    > 1
    > 2>>> d = {'a': 1, 'b': 10, 'c': 100}
    > >>> print_kw(**d)

    >
    > 1
    > 100
    > 10


    Thank you both.
    , May 2, 2007
    #10
  11. Elliot Peele

    Tim Roberts Guest

    Elliot Peele <> wrote:

    >On Tue, 2007-05-01 at 19:27 -0700, 7stud wrote:
    >> On May 1, 7:36 pm, Elliot Peele <> wrote:
    >> > Why does os.path.join('/foo', '/bar') return '/bar' rather than
    >> > '/foo/bar'? That just seems rather counter intuitive.
    >> >
    >> > Elliot

    >>
    >> join( path1[, path2[, ...]])
    >> Join one or more path components intelligently. If any component is an
    >> absolute path, all previous components (on Windows, including the
    >> previous drive letter, if there was one) are thrown away...

    >
    >Yes, but that still doesn't answer my question as to why os.path.join
    >works that way. I understand that that is how it is written, but why?


    It's behavior is exactly the same as if you did a series of "cd" commands
    at the shell with the same parameters.
    --
    Tim Roberts,
    Providenza & Boekelheide, Inc.
    Tim Roberts, May 4, 2007
    #11
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alan Silver
    Replies:
    0
    Views:
    878
    Alan Silver
    Jun 5, 2006
  2. Pierre Fortin

    args v. *args passed to: os.path.join()

    Pierre Fortin, Sep 18, 2004, in forum: Python
    Replies:
    2
    Views:
    686
    Pierre Fortin
    Sep 18, 2004
  3. googleboy
    Replies:
    1
    Views:
    918
    Benji York
    Oct 1, 2005
  4. Steve
    Replies:
    1
    Views:
    962
    Fredrik Lundh
    Dec 13, 2005
  5. =?ISO-8859-1?Q?Gregory_Pi=F1ero?=

    os.path.join - Isn't working

    =?ISO-8859-1?Q?Gregory_Pi=F1ero?=, Jan 27, 2006, in forum: Python
    Replies:
    0
    Views:
    282
    =?ISO-8859-1?Q?Gregory_Pi=F1ero?=
    Jan 27, 2006
Loading...

Share This Page