If I'm given a path as a string, such as "~/pythoncode/*.py" what is the best way to glob it in pathlib
?
Using pathlib, there is a way of appending to a path using a glob:
p = pathlib.Path('~/pythoncode/').expanduser().glob('*.py')
but this, for example, does not work because the user isn't expanded:
p = pathlib.Path().glob('~/pythoncode/*.py')
and this is generates an exception because I'm providing no arguments to glob()
:
p = pathlib.Path('~/pythoncode/*.py').expanduser().glob()
Is there a way to do this in pathlib
, or must I parse the string first?
If you're starting from the string "~/pythoncode/*.py"
and you'd like to expand and glob, you will need to split the path first. Luckily pathlib provides .name
and .parent
to help you out:
def expandpath(path_pattern) -> Iterable[Path]:
p = Path(path_pattern)
return Path(p.parent).expanduser().glob(p.name)
expandpath("~/pythonpath/*.py")
Note this simple solution will only work when only the name
includes a glob, it will not work with globs in other parts of the path, like: ~/python*/*.py
. A more general solution that is a bit more complex:
def expandpath(path_pattern) -> Iterable[Path]:
p = Path(path_pattern).expanduser()
parts = p.parts[p.is_absolute():]
return Path(p.root).glob(str(Path(*parts)))
expandpath("~/python*/*.py")
note-2: the above function fails (IndexError: tuple index out of range
) with these degenerate paths: ''
, '.'
, '/'
pathlib.Path.glob
does not support absolute (non-relative) path patterns, but glob.glob
does:
from glob import glob
from pathlib import Path
paths = [Path(p) for p in glob('/foo/*/bar')]
Or in connection with Path.expanduser
:
paths = [Path(p) for p in glob(str(Path('~/.bash*').expanduser()))]
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