Please help me understand how the builtin os.path.join() function works. For example:
import os
print os.path.join('cat','dog') # 'cat/dog' no surprise here
print os.path.join('cat','dog').join('fish') # 'fcat/dogicat/dogscat/dogh'
On Mac (and i guess linux too) os.name is an alias for posixpath. So looking into the posixpath.py module, the join() function looks like this:
def join(a, *p):
"""Join two or more pathname components, inserting '/' as needed.
If any component is an absolute path, all previous path components
will be discarded. An empty last part will result in a path that
ends with a separator."""
path = a
for b in p:
if b.startswith('/'):
path = b
elif path == '' or path.endswith('/'):
path += b
else:
path += '/' + b
return path
So join() returns a string. Why does os.path.join('something').join('something else') even work? Shouldn't it raise something like 'str' object has no attribute 'join'? I mean if I copy the function some other place and call it like renamed_join('foo','bar') it works as expected but if i do renamed_join('foo','bar').renamed_join('foobar') will raise an AttributeError as expected. Hopefully this is not a very stupid question. It struck me just when I thought I was starting to understand python...
You can't chain os.path.join
like that. os.path.join
returns a string; calling the join
method of that calls the regular string join
method, which is entirely unrelated.
Your second join
call is not os.path.join
, it is str.join
. What this one does is that it joins the argument (as an iterable, meaning it can be seen as f, i, s, h
) with self as the separator (in your case, cat/dog
)
So basically, is puts cat/dog
between every letter of fish
.
Because str
has a join attribute.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With