12

Below shows how I obtained user1's home directory, create a new sub-directory name and create a new sub-directory there via python 3.6's os module.

>>> import os.path
>>> import os
>>> a = os.path.expanduser('~')
>>> a
'/home/user1'
>>> a_sub_dir = a + '/Sub_Dir_1'
>>> a_sub_dir
'/home/user1/Sub_Dir_1'
>>> def create_sub_dir( sub_dir ):
    try:
        os.makedirs( sub_dir, mode=0o777, exist_ok=False )
    except FileExistsError:
        print('Sub_directory already exist, no action taken.')
    else:
        print('Created sub_directory.')
>>> create_sub_dir( a_sub_dir )
Created sub_directory.
>>> create_sub_dir( a_sub_dir )
Sub_directory already exist, no action taken.

I would like to achieve the same as above via python 3.6's pathlib module. However, I can't seem to get it to work (see below). My questions:

  1. How do I use Path.expanduser()?
  2. How do I amend the info in a PosixPath(......) since it is not a string so that I can reuse it?
  3. I would like to amend the PosixPath and use it in my make_sub_dir() function. Will it work? Presently, I explicitly defined the new sub directory that i want to create to check that my make_sub_dir() function works.

Appreciate guidance on how to use pathlib. Thanks in advance.

>>> from pathlib import Path
>>> b = Path.expanduser('~')
Traceback (most recent call last):
  File "<pyshell#87>", line 1, in <module>
    b = Path.expanduser('~')
  File "/usr/lib/python3.6/pathlib.py", line 1438, in expanduser
    if (not (self._drv or self._root) and
AttributeError: 'str' object has no attribute '_drv'
>>> b = Path.expanduser('~/')
Traceback (most recent call last):
  File "<pyshell#88>", line 1, in <module>
    b = Path.expanduser('~/')
  File "/usr/lib/python3.6/pathlib.py", line 1438, in expanduser
    if (not (self._drv or self._root) and
AttributeError: 'str' object has no attribute '_drv'
>>> b = Path.home()
>>> b
PosixPath('/home/user1')
>>> b_sub_dir = b + '/Sub_Dir_1'
Traceback (most recent call last):
  File "<pyshell#91>", line 1, in <module>
    b_sub_dir = b + '/Sub_Dir_1'
TypeError: unsupported operand type(s) for +: 'PosixPath' and 'str'
>>> def make_sub_dir( sub_dir ):
    try:
        Path(sub_dir).mkdir(mode=0o777, parents=False, exist_ok=False)
    except FileNotFoundError:
        print('Parent directory do not exist, no action taken.')
    except FileExistsError:
        print('Sub_directory already exist, no action taken.')
    else:
        print('Created sub_directory.')
>>> make_sub_dir( '/home/user1/Sub_Dir_1' )
Sub_directory already exist, no action taken.
>>> make_sub_dir( '/home/user1/Sub_Dir_1' )
Created sub_directory.
>>> make_sub_dir( '/home/user1/Sub_Dir_1' )
Sub_directory already exist, no action taken.
Sun Bear
  • 7,594
  • 11
  • 56
  • 102
  • 3
    FYI you should **not** user string concatenation to join paths, not even when using `os.path`... you should use `os.path.join`. – Giacomo Alzetta Jul 29 '19 at 07:22

1 Answers1

22

pathlib's expanduser works differently than the one in os.path: it is applied to a Path object and takes no arguments. as shown in the doc you can either use:

>>> from pathlib import Path
>>> p = Path('~/films/Monty Python')
>>> p.expanduser()
PosixPath('/home/eric/films/Monty Python')

or work with .home():

>>> form pathlib import Path
>>> Path.home()
PosixPath('/home/antoine')

then in order to join directories you should use / (instead of +):

b_sub_dir = b / 'Sub_Dir_1'
ryantuck
  • 6,146
  • 10
  • 57
  • 71
hiro protagonist
  • 44,693
  • 14
  • 86
  • 111
  • It just dawn on me that for question 1, I should have written it as `b = Path('~').expanduser()`. – Sun Bear Jul 29 '19 at 07:22
  • Earlier, I had tried `p = PosixPath('~/films/Monty Python')` but got a `NameError`. Traceback (most recent call last): File "", line 1, in p = PosixPath('~/films/Monty Python') NameError: name 'PosixPath' is not defined – Sun Bear Jul 29 '19 at 07:27
  • `import PosixPath` Traceback (most recent call last): File "", line 1, in import PosixPath ModuleNotFoundError: No module named 'PosixPath' – Sun Bear Jul 29 '19 at 07:29
  • should be `from pathlib import Path` (or `PosixPath` if you prefer; but `Path` may be more portable). – hiro protagonist Jul 29 '19 at 07:31
  • Noted that `/` can be used to add directory name. How do I subtract a directory name from the PosixPath? – Sun Bear Jul 29 '19 at 07:39
  • 'subtract' is either `path / '..'` or [`path.parent`](https://docs.python.org/3/library/pathlib.html#pathlib.PurePath.parent). – hiro protagonist Jul 29 '19 at 07:42