python pathlib operator '/' – how does it do it?
Question:
I found the pathlib syntax – or is it the Python syntax – surprising. I’d like to know how this makes the forward slash /
act as a joiner of WindowsPath
s etc. Does it override/overload /
? It seems to be in a magical context, the slash is between a WindowsPath
type object and a string. If I try between 2 strings it fails to join the 2 strings (e.g. "123" / "123"
fails)
p=pathlib.Path(".")
p
Out[66]: WindowsPath('.')
p.cwd()
Out[67]: WindowsPath('C:/Users/user1')
p.cwd() / "mydir"
Out[68]: WindowsPath('C:/Users/user1/mydir')
Answers:
The Path class has a __truediv__
method that returns another Path. You can do the same with your own classes:
>>> class WeirdThing(object):
def __truediv__(self, other):
return 'Division!'
>>> WeirdThing() / WeirdThing()
'Division!'
For whoever wants to see the source code briefly:
__truediv__
overload the /
operator, and returns self
, which is a Path
object.
# this is where the magic begins! (overload the '/' operator)
def __truediv__(self, key):
try:
return self._make_child((key,))
except TypeError:
return NotImplemented
def _make_child(self, args):
drv, root, parts = self._parse_args(args)
drv, root, parts = self._flavour.join_parsed_parts(
self._drv, self._root, self._parts, drv, root, parts)
return self._from_parsed_parts(drv, root, parts)
@classmethod
def _from_parsed_parts(cls, drv, root, parts):
self = object.__new__(cls)
self._drv = drv
self._root = root
self._parts = parts
return self # finally return 'self', which is a Path object.
I found the pathlib syntax – or is it the Python syntax – surprising. I’d like to know how this makes the forward slash /
act as a joiner of WindowsPath
s etc. Does it override/overload /
? It seems to be in a magical context, the slash is between a WindowsPath
type object and a string. If I try between 2 strings it fails to join the 2 strings (e.g. "123" / "123"
fails)
p=pathlib.Path(".")
p
Out[66]: WindowsPath('.')
p.cwd()
Out[67]: WindowsPath('C:/Users/user1')
p.cwd() / "mydir"
Out[68]: WindowsPath('C:/Users/user1/mydir')
The Path class has a __truediv__
method that returns another Path. You can do the same with your own classes:
>>> class WeirdThing(object):
def __truediv__(self, other):
return 'Division!'
>>> WeirdThing() / WeirdThing()
'Division!'
For whoever wants to see the source code briefly:
__truediv__
overload the /
operator, and returns self
, which is a Path
object.
# this is where the magic begins! (overload the '/' operator)
def __truediv__(self, key):
try:
return self._make_child((key,))
except TypeError:
return NotImplemented
def _make_child(self, args):
drv, root, parts = self._parse_args(args)
drv, root, parts = self._flavour.join_parsed_parts(
self._drv, self._root, self._parts, drv, root, parts)
return self._from_parsed_parts(drv, root, parts)
@classmethod
def _from_parsed_parts(cls, drv, root, parts):
self = object.__new__(cls)
self._drv = drv
self._root = root
self._parts = parts
return self # finally return 'self', which is a Path object.