Files
second-brain/Clippings/Why I Prefer “import x” Over “from x import y”.md

146 lines
5.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Why I Prefer “import x” Over “from x import y”"
source: "https://levelup.gitconnected.com/why-i-prefer-import-x-over-from-x-import-y-b1ae8be6cbdd"
author:
- "[[Liu Zuo Lin]]"
published: 2024-05-18
created: 2024-10-29
description: "^ we can import the entire module b, and the use b.<function_name> to access the individual functions defined in b.py Here, when we use the functions defined in b.py, we need to put the module name b…"
tags:
- "clippings"
---
[
![Liu Zuo Lin](https://miro.medium.com/v2/resize:fill:88:88/1*Z5dMY4-vS6G69lMMdn3xIQ.jpeg)
](https://zlliu.medium.com/?source=post_page---byline--b1ae8be6cbdd--------------------------------)
[
![Level Up Coding](https://miro.medium.com/v2/resize:fill:48:48/1*5D9oYBd58pyjMkV_5-zXXQ.jpeg)
](https://levelup.gitconnected.com/?source=post_page---byline--b1ae8be6cbdd--------------------------------)
![](https://miro.medium.com/v2/resize:fit:700/1*DDmEVeU3SLFRZbUEXUhxZw.png)
Both ways are correct, but one way is more correct than another. In my opinion, at least.
## Importing in Python
Lets say we have 2 Python files:
- `a.py` which we run directly using the command `python a.py`
- `b.py` which contains functions that are *imported* into `a.py`
```
def test(): print('test')def hello(): print('hello')
```
^ there are 2 main ways to import the functions from `b.py` into `a.py`
## 1) import b
```
import bb.test() b.hello()
```
^ we can import the entire module `b`, and the use `b.<function_name>` to access the individual functions defined in `b.py`
Here, when we use the functions defined in `b.py`, we need to put the module name `b` beforehand eg `b.test()` or `b.hello()`
## 2) from b import <function>
```
from b import test, hellotest() hello()
```
^ alternatively, we can also use `from b import test, hello` to import the functions directly.
Here, we dont need to put `b` before our function name — we can use the function name directly.
> Why I prefer import b over from b import test, hello
## 1) Namespace issues
When we use `import b` instead of `from b import test, hello`, we are less likely to have a clash in namespace.
```
def test(): print('test')def hello(): print('hello')
```
```
test = 'apple'from b import test, hello
```
^ when we `from b import test, hello` inside `a.py`, we directly use the `test` and `hello` variables. If we are not careful, we might accidentally override any existing `test` and `hello` variables.
- `test` is already defined in `a.py`
- when we `from b import test`, we import `test` from `b.py`
- `test` from `b.py` overrides the original `test` from `a.py`
Note that this problem gets exponentially worse as our Python scripts become increasingly complicated, containing more and more variables that might clash with each other.
```
def test(): print('test')def hello(): print('hello')
```
```
test = 'apple'import bb.test()b.hello()
```
^ however, if we use `import b`, we need to use `b.test()` in order to access the `test` function inside `b.py`
This does not in fact clash with our original `test` variable in `a.py` as they are using different namespaces. Which means that we are much less likely to accidentally override our variables.
## 2) Less clutter
I firsthandedly experienced this recently at work.
```
def doSomethingHappily(): passdef doSomethingSadly(): passdef doSomethingAngrily(): passdef doSomethingQuickly(): passdef doSomethingSlowly(): passdef doSomethingElse(): pass
```
^ I had a bunch of functions (with pretty lengthy names) in `b.py`, and I needed to import them into `a.py`
```
from b import doSomethingHappily, doSomethingSadly, doSomethingAngrily \ doSomethingQuickly, doSomethingSlowly, doSomethingElsedoSomethingHappily()doSomethingSadly()doSomethingAngrily()doSomethingQuickly()doSomethingSlowly()doSomethingElse()
```
^ this was what my import statement was like. Some problems:
- there was lots of clutter and this took up lots of random space
- if I changed a function name, I needed to change it multiple times in `a.py` too
- which got annoying pretty quickly
Instead, I refactored my import statement to `import b`
```
import bb.doSomethingHappily()b.doSomethingSadly()b.doSomethingAngrily()b.doSomethingQuickly()b.doSomethingSlowly()b.doSomethingElse()
```
- my import statement no longer spanned multiple lines
- when I modified a function name, I no longer had to change this in multiple places
## Why not “from b import \*”?
This is bad practice, so while this is *legal* code, chances are the the senior devs might not want this around.
But why is this bad practice? `from b import *` means import *everything* from inside `b.py`. Which means we are even more likely to accidentally override some variables in our namespace now.
As good practice, we should ideally import only what we need rather than every single thing inside a module.
## Conclusion
Hope this was clear and easy to understand
## If You Wish To Support Me As A Creator
1. *Clap 50 times for this story*
2. *Leave a comment telling me your thoughts*
3. *Highlight your favourite part of the story*
*Thank you! These tiny actions go a long way, and I really appreciate it!*
**YouTube:** [**https://www.youtube.com/@zlliu246**](https://www.youtube.com/@zlliu246)
**LinkedIn:** [**https://www.linkedin.com/in/zlliu/**](https://www.linkedin.com/in/zlliu/)
**My Ebooks:** [**https://zlliu.co/ebooks**](https://zlliu.co/ebooks)