# Reducing repetition when using import

**URL:** <https://discuss.python.org/t/reducing-repetition-when-using-import/20184>\
**Category:** Python Help\
**Created:** [October 21, 2022, 1:58pm UTC](https://discuss.python.org/t/reducing-repetition-when-using-import/20184 "2022-10-21T13:58:04Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![vainaixr](https://avatars.discourse-cdn.com/v4/letter/v/5f8ce5/32.png) [@vainaixr](https://discuss.python.org/u/vainaixr)\
**Post date:** [October 21, 2022, 1:58pm UTC](https://discuss.python.org/t/reducing-repetition-when-using-import/20184/1 "2022-10-21T13:58:04Z")

</div>

current scenario -

1. 

```auto
from a.b.c import d
from a.b.e import f
from a.b.g import h

```

the `a.b` part keeps repeating

1. one way to reduce this repetition is,

```auto
dct = {'c': 'd', 'e': 'f', 'g': 'h'}
[exec("from a.b.{key} import {value}") for key, value in dct.items()]

```

but it requires using `exec`, I am not sure if this is a recommended way to achieve the same

expected scenario -

1. if there is someway to achieve this without using `exec` then inform me
2. if not, then I think there should be some way to reduce this repetition

---

<div class="post-metadata">

**Author:** ![facelessuser](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/facelessuser/32/1971_2.png) [@facelessuser](https://discuss.python.org/u/facelessuser)\
**Post date:** [October 21, 2022, 2:27pm UTC](https://discuss.python.org/t/reducing-repetition-when-using-import/20184/2 "2022-10-21T14:27:17Z")

</div>

There are certainly better ways to import things than using `exec`, I’d check out [`importlib`](https://docs.python.org/3/library/importlib.html).

There are times when a dynamic import may be required, and something like `importlib` is usually the way to go for such cases. With that said, if we are talking about normal importing, I would just stick with the usual repetitive `from ... import ...` approach.

More compact code isn’t necessarily “better”. I personally find the second example more convoluted. The second example also isn’t more efficient, it is just more compact. I don’t think you really gain anything from reducing the repetition except less repetition. On the other hand, you lose readability, you incur a higher maintenance burden, and you import in a less efficient manner.

---

<div class="post-metadata">

**Author:** ![vainaixr](https://avatars.discourse-cdn.com/v4/letter/v/5f8ce5/32.png) [@vainaixr](https://discuss.python.org/u/vainaixr)\
**Post date:** [October 21, 2022, 3:01pm UTC](https://discuss.python.org/t/reducing-repetition-when-using-import/20184/3 "2022-10-21T15:01:46Z")

</div>

I want to know should `exec` be completely avoided, or is it only if it asks for user input that it should be avoided, I dont see what could be the issue with,

```auto
exec("import fastapi")

```

or the op `exec` example.

there could be issue with,

```auto
exec('input()')

```

or any command which requires user input.

---

<div class="post-metadata">

**Author:** ![facelessuser](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/facelessuser/32/1971_2.png) [@facelessuser](https://discuss.python.org/u/facelessuser)\
**Post date:** [October 21, 2022, 3:22pm UTC](https://discuss.python.org/t/reducing-repetition-when-using-import/20184/4 "2022-10-21T15:22:32Z")

</div>

> [@vainaixr](#):
>
> I want to know should `exec` be completely avoided, or is it only if it asks for user input that it should be avoided, I dont see what could be the issue with,

There is not a fundamental issue per se. I think some people would have strong feelings about the approach, but I guess those could be argued as subjective.

---

<div class="post-metadata">

**Author:** ![vbrozik](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/vbrozik/32/7423_2.png) [@vbrozik](https://discuss.python.org/u/vbrozik)\
**Post date:** [October 21, 2022, 3:43pm UTC](https://discuss.python.org/t/reducing-repetition-when-using-import/20184/5 "2022-10-21T15:43:11Z")

</div>

> [@vainaixr](#):
>
> I want to know should `exec` be completely avoided, or is it only if it asks for user input that it should be avoided, I dont see what could be the issue with,

It should be completely avoided if you do not have extremely good control over the content to be executed. So it is not just user input but also API input, configuration files etc. Practically any data which could come from outside of the application should not make a part of code to be executed or you have to sanitize them extremely thoroughly.

…but that is not all. There are other problems with `exec()` (and similar):

- broken linting
- broken type checking
- boken syntax highlighting
- complications in debugging and error handling

I think you got the idea.

* * *

> [@vainaixr](#):
>
> there could be issue with,
> 
> ```auto
> exec('input()')
> 
> ```

I am not sure where you see problems with that. Problematic is when the external data make part of the code to be executed.

---

<div class="post-metadata">

**Author:** ![steven.daprano](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steven.daprano/32/1083_2.png) [@steven.daprano](https://discuss.python.org/u/steven.daprano)\
**Post date:** [October 21, 2022, 10:43pm UTC](https://discuss.python.org/t/reducing-repetition-when-using-import/20184/6 "2022-10-21T22:43:53Z")

</div>

> [@](#):
>
> ```auto
> from a.b.c import d
> from a.b.e import f
> from a.b.g import h
> 
> ```
> 
> the `a.b` part keeps repeating

So what? Why do you care? This is harmless repetition. It is not just harmless, it is **good repetition** – it repeats the part of the code which has to repeat. Avoiding that natural repetition requires the most unnatural, complicated and inefficient code.

If you find that in practice this is painful, that’s probably a sign that your package is badly designed, with too many levels, and you should refactor it to something like:

```auto
from a import d, f, h

```

> [@](#):
>
> 1. one way to reduce this repetition is,
> 
> ```auto
> dct = {'c': 'd', 'e': 'f', 'g': 'h'}
> [exec("from a.b.{key} import {value}") for key, value in dct.items()]
> 
> ```

Yeah, that’s awful code. It is worse than the original in **every** way except one **very minor** advantage:

- Save one line of code (2 lines instead of 3).

And even that advantage is only because you have artificially short names: “a”, “b”, “c” etc instead of realistic meaningful names. With more realistic names, you possibly will end up exceeding the recommended 79 char line length and will split one or both of the lines.

Compared to that, you haven’t reduced the repetition, you have just disguised it. In addition, the second version:

- Is harder to read and understand.
- Is less natural and straight-forward code.
- Is less efficient and slower code.
- It wastefully creates a list filled with None that has to garbage collected.
- It defeats code analysis tools like linters.
- It defeats code completion and syntax highlighting.
- It is longer to type: 105 characters compared to 57.
- It is _more fragile_ code: because it does more work, there are more things to go wrong.
- And it is harder to maintain if there are future changes.

E.g. if you refactor module `a.b.d` into `a.x.y.z` your shortcut doesn’t work and has to be completely changed. You can’t insert logging or print between two of the imports.

---

<div class="post-metadata">

**Author:** ![steven.daprano](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steven.daprano/32/1083_2.png) [@steven.daprano](https://discuss.python.org/u/steven.daprano)\
**Post date:** [October 21, 2022, 10:59pm UTC](https://discuss.python.org/t/reducing-repetition-when-using-import/20184/7 "2022-10-21T22:59:10Z")

</div>

> [@](#):
>
> I want to know should `exec` be completely avoided

For beginners to Python: never use exec.

For intermediate and expert users: _almost_ never use exec.

> [@](#):
>
> I dont see what could be the issue with,
> 
> ```auto
> exec("import fastapi")
> 
> ```

There is never a good reason to write a call to exec like that, where the code is a fixed string literal.

It _might_ be useful, sometimes, to build some source code dynamically, at runtime, and then `exec` it. But if you know what the source code is ahead of time, when you are writing the program, you should just _write that code_ and not wrap it into a string literal and exec it.

The overhead of `exec` is considerable: it has to parse and byte-code compile the source code, _at runtime_. So it cannot take advantage of pre-compiled .pyc files.

Even for importing modules, which is an expensive operation, this overhead is considerable:

```auto
[steve ~]$ python3.10 -m timeit "import this"
The Zen of Python, by Tim Peters
...
2000000 loops, best of 5: 104 nsec per loop
[steve ~]$ python3.10 -m timeit "exec('import this')"
The Zen of Python, by Tim Peters
...
50000 loops, best of 5: 7.46 usec per loop

```

---

<div class="post-metadata">

**Author:** ![aivarpaalberg](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/aivarpaalberg/32/9457_2.png) [@aivarpaalberg](https://discuss.python.org/u/aivarpaalberg)\
**Post date:** [October 22, 2022, 8:51am UTC](https://discuss.python.org/t/reducing-repetition-when-using-import/20184/8 "2022-10-22T08:51:43Z")

</div>

Just as general note: [PEP 8 - Style Guide for Python Code - Imports](https://peps.python.org/pep-0008/#imports)
