avatarLiu Zuo Lin

Summary

The provided content discusses six lesser-known aspects of Python import mechanisms, including the use of __import__, __all__, absolute and relative imports, the sys.path list, and the if __name__ == '__main__' conditional for controlling script execution.

Abstract

The article "6 Things I Never Knew About Python Imports Until Recently" delves into advanced Python import features that may not be widely known among developers. It covers the direct use of the __import__ function for dynamic module loading, the __all__ variable for specifying which functions or classes are available for import *, and the differences between absolute and relative imports, which are crucial for organizing code in large projects. The author also explains how sys.path determines where Python looks for modules and how to manipulate it for custom import paths. Additionally, the article highlights the importance of the if __name__ == '__main__' conditional to ensure code execution only when a script is run directly, not when it is imported as a module. These insights aim to enhance the reader's understanding of Python's import system and improve their coding practices.

Opinions

  • The author believes that understanding the intricacies of Python's import system is crucial for developers to effectively manage and structure their code.
  • The use of __import__ is presented as a powerful feature for dynamic module loading, suggesting flexibility in how modules are handled in Python.
  • The __all__ mechanism is recommended for controlling the exported objects from a module, thus promoting better encapsulation and cleaner interfaces.
  • Absolute imports are encouraged for clarity and avoiding potential conflicts in module names, especially in complex directory structures.
  • The manipulation of sys.path is suggested as a practical solution for importing modules from non-standard locations, which can be particularly useful in custom development environments.
  • The article conveys that the if __name__ == '__main__' conditional is an essential tool for preventing unintended code execution when modules are imported, thereby enhancing code organization and maintainability.
  • The author emphasizes the clarity and ease of understanding of the presented concepts, indicating a commitment to educational outreach and the accessibility of technical content.
  • The conclusion of the article implies that the reader's engagement with the content (such as clapping, commenting, and highlighting) is valuable and appreciated by the author, suggesting a community-driven approach to learning and sharing knowledge.

6 Things I Never Knew About Python Imports Until Recently

Day 42 of experimenting with video content.

1) __import__

Our normal way of importing stuff eg. pandas

import pandas as pd

df = pd.DataFrame()

Using __import__

pd = __import__('pandas')

df = pd.DataFrame()

2) __all__

Let’s say we have 2 files a.py and b.py

# a.py

from b import *
# b.py

def test1():
  pass

def test2():
  pass

def test3():
  pass

Currently, a.py will import everything from b.py due to the from b import * statement. However, this might change if we add __all__ to b.py

# a.py

from b import *
# b.py

def test1():
  pass

def test2():
  pass

def test3():
  pass

__all__ = ['test1', 'test2']

Here, the __all__ list defines what will be imported from b.py when the statement from b import * is used. In this case, only test1 and test2 will be imported from b.py, and test3 will not be.

3) absolute imports

Let’s say we have a hello.py nested deep within a bunch of folders:

test1
  |-test2
    |-test3
      hello.py
a.py

Contents of hello.py:

def hello():
  print('hello')

Now, let’s say we are using a.py and we wish to import the hello function from hello.py. To do this, we can use absolute imports.

# a.py

from test1.test2.test3.hello import hello

hello()

# hello

4) if __name__ == ‘__main__’

Let’s say we have 2 files in the same folder, a.py and b.py

# a.py

from b import *

if __name__ == '__main__':
  print('only runs when i run a.py directly')
# b.py

def hello_from_b():
  print('hello from b.py')

if __name__ == '__main__':
  print('only runs when i run b.py directly')

When I run a.py directly, I get only runs when i run a.py directly only. Whatever is inside if __name__ == '__main__' of b.py does not run UNLESS I explicitly run b.py itself.

This is useful to prevent ourselves from accidentally running code that we don’t want to run.

When we run a Python script directly eg a.py, __name__ in a.py will be '__main__'. But all other __name__ in other files will be equal to their Python script name eg. b.py's __name__ will be b. Which is why the if statement if __name__ == '__main__' works.

5) sys.path and importing

import sys

print(sys.path)

# ['/Users/zlliu/repos/main', 
#  '/Library/Frameworks/Python.framework/Versions/3.12/lib/python312.zip'
# ...
# ]

# list of absolute paths Python will search to import stuff from

Here, when we print sys.path, we will get a list of absolute paths (as strings in a list). These paths are the paths that Python will search for when attempting to import stuff.

Which means that we can actually manually add our own paths into sys.path if we want Python to import stuff from some weird folder in our computer.

Let’s say we have some modules in our directory /apple/orange/pear which we want to import from.

import sys

sys.path.append('/apple/orange/pear')

Now, since /apple/orange/pear is in sys.path, Python will search this directory when importing stuff, and we will be able to import stuff from this directory.

6) relative imports

Let’s say we have 3 files

test
  |- b.py
  |- c.py
a.py
  • a.py imports from b.py
  • b.py imports from c.py
# c.py

def hello_from_c():
  print('hello')
# b.py

from .c import hello_from_c
# a.py

from test.b import hello_from_c

hello_from_c()
# hello

Here, the statement from .c import hello_from_c is a relative import. The . in front means that c is in the SAME directory.

This can be useful if our absolute paths are pretty long and we don’t wish to type them all out.

Conclusion

Hope this was clear and easy to understand.

Some Final words

If this story was helpful and you wish to show a little support, you could:

  1. Clap 50 times for this story
  2. Leave a comment telling me what you think
  3. Highlight the parts in this story that resonate with you

These actions really really help me out, and are much appreciated!

Ebooks I’ve Written: https://zlliu.co/ebooks

LinkedIn: https://www.linkedin.com/in/zlliu/

Python
Programming
Coding
Code
Python3
Recommended from ReadMedium