{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Path Management\n", "\n", "\n", "## Goal\n", " \n", " - Normalize paths on different platform\n", " - Create, copy and remove folders\n", " - Handle errors\n", " \n", "## Modules\n", " " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import os\n", "import os.path\n", "import shutil\n", "import errno\n", "import glob\n", "import sys" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## See also:\n", "\n", " - pathlib on Python 3.4+" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Be python3 ready\n", "from __future__ import unicode_literals, print_function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Multiplatform Path Management\n", "\n", "1- The os.path module seems verbose\n", " but it's the *best* way to manage paths. It's:\n", " - safe\n", " - multiplatform\n", "\n", " \n", "2- Here we check the operating system\n", " and prepend the right path\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import os\n", "import sys\n", "basedir, hosts = \"/\", \"etc/hosts\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# sys.platform shows the current operating system\n", "if sys.platform.startswith('win'):\n", " basedir = 'c:/windows/system32/drivers'\n", "print(basedir)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Join removes redundant \"/\"\n", "hosts = os.path.join(basedir, hosts)\n", "print(hosts)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# normpath fixes \"/\" orientation \n", "# and redundant \"..\"\n", "hosts = os.path.normpath(hosts)\n", "print(\"Normalized path is\", hosts)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# realpath resolves symlinks (on unix)\n", "! mkdir -p /tmp/course\n", "! ln -sf /etc/hosts /tmp/course/hosts\n", "realfile = os.path.realpath(\"/tmp/course/hosts\") \n", "print(realfile)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Exercise: given the following path\n", "base, path = \"/usr\", \"/bin/foo\"\n", "# Which is the expected output of result?\n", "result = os.path.join(base, path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Manage trees\n", "\n", "Python modules can:\n", " - manage directory trees\n", " - and basic errors\n", "\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# os and shutil supports basic file operations\n", "# like recursive copy and tree creation.\n", "from os import makedirs\n", "makedirs(\"/tmp/course/foo/bar\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# while os.path can be used to test file existence\n", "from os.path import isdir\n", "assert isdir(\"/tmp/course/foo/bar\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Check the directory content with either one of\n", "!tree /tmp/course || find /tmp/course" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# We can use exception handlers to check\n", "# what happened.\n", "\n", "try:\n", " # python2 does not allow to ignore\n", " # already existing directories\n", " # and raises an OSError\n", " makedirs(\"/tmp/course/foo/bar\")\n", "except OSError as e:\n", " # Just use the errno module to\n", " # check the error value\n", " print(e)\n", " import errno\n", " assert e.errno == errno.EEXIST" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from shutil import copytree, rmtree\n", "# Now copy recursively two directories\n", "# and check the result\n", "copytree(\"/tmp/course/foo\", \"/tmp/course/foo2\")\n", "assert isdir(\"/tmp/course/foo2/bar\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "#This command should work on both unix and windows \n", "!dir /tmp/course/foo2/" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Now remove it and check the outcome\n", "rmtree(\"/tmp/course/foo\")\n", "assert not isdir(\"/tmp/course/foo/bar\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "#This command should work on both unix and windows \n", "!dir /tmp/course/" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Cleanup created files\n", "rmtree(\"/tmp/course\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.12" } }, "nbformat": 4, "nbformat_minor": 0 }