Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Diving deep on how imports work in Python

Diving deep on how imports work in Python

Talk was given on PyCon Taiwan 2017

Talk link: https://tw.pycon.org/2017/en-us/events/talk/342865744498786414/

Tasdik Rahman

June 12, 2017
Tweet

More Decks by Tasdik Rahman

Other Decks in Programming

Transcript

  1. Diving deep on how imports
    work in Python
    PyCon Taiwan, 2017
    presented by Tasdik Rahman (@tasdikrahman)

    View Slide

  2. But Why?

    View Slide

  3. Modules

    View Slide

  4. Terminology
    •Loader
    Loads a module
    •Finder
    Finds a module

    View Slide

  5. Module search path

    View Slide

  6. sys.path

    View Slide

  7. >>> import sys
    >>>
    >>> pprint(sys.path)
    ['',
    '/usr/local/Cellar/python3/3.6.0/Frameworks/
    Python.framework/Versions/3.6/lib/python36.zip',
    '/usr/local/Cellar/python3/3.6.0/Frameworks/
    Python.framework/Versions/3.6/lib/python3.6',
    '/usr/local/Cellar/python3/3.6.0/Frameworks/
    Python.framework/Versions/3.6/lib/python3.6/lib-
    dynload',
    '/usr/local/lib/python3.6/site-packages']
    >>>

    View Slide

  8. Compiled Python files

    View Slide

  9. • __pycache__ under a name like module.version.pyc
    • __pycache__/spam.cpython-33.pyc
    • platform independent
    • regular lookup with source checking for modification.

    View Slide

  10. import foo

    View Slide

  11. 2 step process
    • find a module, loading and
    initialising it if necessary
    • define a name or names in the local
    namespace for the scope where the
    "import" statement occurs.

    View Slide

  12. If module is retrieved
    successfully

    View Slide

  13. import foo # foo imported and bound locally
    import foo.bar.baz 

    # foo.bar.baz imported, foo bound locally
    import foo.bar.baz as fbb 

    # foo.bar.baz imported and bound as fbb

    View Slide

  14. from foo.bar import baz

    View Slide

  15. • find the module specified in the "from" clause, loading and
    initialising if necessary
    • for each of the identifiers specified in the "import" clauses:
    1. check if the imported module has an attribute by that name
    2. attempt to import a submodule with that name and check the
    imported module again for that attribute
    3. if the attribute is not found, "ImportError" is raised.

    View Slide

  16. from foo.bar import baz
    # foo.bar.baz imported and bound as baz
    from foo import attr
    # foo imported and foo.attr bound as attr

    View Slide

  17. from foo import *

    View Slide

  18. Packages

    View Slide

  19. Advantages?

    View Slide

  20. car/ Top-level package
    __init__.py Initialize the car package
    engine/ Subpackage for engine behaviour
    __init__.py
    rev.py
    temperature.py
    fuel.py
    coolant.py
    ...
    transmission/ Subpackage for transmission
    __init__.py
    forward.py
    reverse.py
    ...
    infotainment/ Subpackage for infotainment system
    __init__.py
    music.py
    reverseparking.py
    chilledbeer.py
    ...

    View Slide

  21. __init__.py

    View Slide

  22. import car.engine.rev
    car.engine.rev.spin(…)
    # OR
    from car.engine import rev
    rev.spin(...)
    # OR
    from car.engine.rev import spin
    spin(...)

    View Slide

  23. __all__

    View Slide

  24. from car.engine import *
    # car/engine/__init__.py
    __all__ = ["temperature", "fuel", "coolant"]

    View Slide

  25. What if there is no
    __all__ ?

    View Slide

  26. Intra-package
    reference

    View Slide

  27. # car/engine/temperature
    from car.transmission import forward
    from . import forward
    from .. import transmission
    from ..infotainment import music

    View Slide

  28. Some takeaways

    View Slide

  29. Questions?


    Would be happy to take them :)
    http://tasdikrahman.me/

    @tasdikrahman

    View Slide