Question or issue on macOS:
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…
How to solve this problem?
Solution no. 1:
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.
Solution no. 2:
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,
So basically, is puts
cat/dog between every letter of
str has a join attribute.