0

In Python3, the unfortunate decision was made to remove the functionality of relative imports. I'm currently in the process of modernizing a large amount of Python2 code that makes some heavy use of this feature.

So, right now, I have code that is to the effect of:

import other_function
import another_class_file
...
foo = other_function.calculate_foo() + other_function.constant
bar = another_class_file.Bar(foo)

And as far as I am aware, the "correct" way to do this in Python3 is to:

from other_function import foo as calculate_foo
from other_function import constant
from another_class_file import Bar
....
foo = calculate_foo() + constant
bar = Bar(foo)

But this way feels extremely filthy: instead of always knowing exactly where a function or class comes from, it's all just getting thrown at the top level, and the only way of knowing where something comes from is by looking at the list of import statements at the top. Overall, the code becomes much more ambiguous as a result; explicit is better than implicit.

Is there any way I could achieve the same notation, something akin to from other_function import foo as other_function.calculate_foo? I do not want to have to manually name these things Hungarian-style.

1 Answer 1

5

Relative imports still exist in Python 3. Even if they had been removed, your second code snippet wouldn't address the problem. It looks like you've gotten seriously confused about what a relative import actually is.

Relative imports are when code inside a package - say, in the pkg.mod submodule of package pkg - imports other contents of the same package without needing to repeat the pkg part. On Python 2, if pkg.mod wanted to import pkg.mod2, it could do

import mod2

which was an implicit relative import. Those had a lot of ambiguity problems, so explicit relative import syntax was introduced:

from . import mod2

On Python 3, implicit relative import syntax has been disabled in favor of the explicit syntax. On Python 2, implicit relative import syntax still exists, but explicit syntax is strongly preferred, and the implicit syntax can be disabled with from __future__ import absolute_import.


It doesn't look like your code is using packages or any sort of relative imports. You should be able to continue on using the same import syntax you used previously.

If other_function and another_class_file are sibling submodules inside a package, then the necessary syntax change would be

from . import other_function
from . import another_class_file
Sign up to request clarification or add additional context in comments.

4 Comments

This does not work in my case. If other_function.py and another_class_file.py are in the same directory as the main script, Python will raise an ImportError if I attempt from . import other_function, another_class_file. Is there something obvious I'm missing here?
@AmphotericLewisAcid: Like I said, it doesn't look like your code is using packages or any sort of relative imports. (Two files being in the same directory doesn't make them package submodules or mean they need to use relative imports to access each other.) Whatever problem you were having originally, it doesn't sound related to relative imports.
I see exactly what was going on. My IDE was highlighting it as a code-breaking error, because the files are not modules. But the code itself runs just fine. I'm going to leave this up long enough for you to see it, then I'll delete the question to avoid polluting the forum with more un-needed questions.
Sounds like you might need to reorganize or reclassify the files in your IDE.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.