2

I have import.py script. I want to extract some code into a separate file, say, m1.py:

$ ls
import.py  m1.py

$ cat import.py
from .m1 import a
a()

$ cat m1.py
def a():
    print('it works')

$ python import.py
Traceback (most recent call last):
  File "import.py", line 1, in <module>
    from .m1 import a
ModuleNotFoundError: No module named '__main__.m1'; '__main__' is not a package

When I switch to absolute import, it works. But I don't want accidentally importing other module. I want to be sure module from script's directory is imported. How do I make it work? Or what am I doing wrong?

x-yuri
  • 16,722
  • 15
  • 114
  • 161

2 Answers2

1

If you're not overriding the built in modules. By default, python looks first in your current directory for the file name you want to import. So if there is another script having the same name in another directory, only the one you have in the current directory is the one that will be imported.

Then, you could import using the absolute import.

from m1 import a
a()

You can check this post out, for more infrotmation about importing in python.

To make sure that the one your importing isn't the built in. You can create your own package in the current directory for example,"my_package" and have your module m1 moved in it. Then you can import by:

from my_package import m1
m1.a()
omargamal8
  • 551
  • 5
  • 12
  • The [doc](https://docs.python.org/3/tutorial/modules.html#the-module-search-path) says, "When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable [sys.path](https://docs.python.org/3/library/sys.html#sys.path)." So I can't override built-in module with module from script's directory. – x-yuri Jun 13 '17 at 14:22
  • Yes, you are write. What I said above will work if your overriding a module located one of your PATH directories. You can make sure by creating your own package. In the current directory create folder called "my_package" in that folder create an "\_\_init\_\_".py then move your m1.py file in the my_package folder. Then import by saying from my_package import m1 m1.a() – omargamal8 Jun 14 '17 at 00:25
  • I was just correcting your words (the ones in the answer, concerning built-in modules). I like your answer more. As for creating a package, what difference would that make? – x-yuri Jun 14 '17 at 01:14
  • Nothing really, Creating a package is just a way to organize your modules. You can group modules that are some how related, in one package. So Instead of filling your main directory with bunch of individual files you can have a packages, and each package contains some modules. For ex: I can create a package "Communication" which contains all modules that my main script communicate with, and so on. – omargamal8 Jun 14 '17 at 01:27
  • Can you show where documentation says that modules from packages are looked first, before built-in modules? From what I can see, there's no exception for packages. If built-in module exists, it's it that will be imported, not a module from a package. – x-yuri Jun 14 '17 at 08:10
  • 1
    No it's not like that, I am not trying to override the built in module by that. It's more of addressing the full path of the module that you want to import. So instead of just specifying the name of the module, we are specifying the parent package that the module is found in. The only way you will import a built in module like that, is if there is a built in package\module called my_package and inside that package there is a module called m1. – omargamal8 Jun 16 '17 at 05:31
0

Add __init__.py in the directory where m1.py is.
EDIT : Run it as a package from the previous working directory. cd .. && python -m prev_dir.import

Sachin
  • 3,576
  • 1
  • 15
  • 24
  • 1
    One might probably add here, that relative imports are [not available](https://docs.python.org/3/tutorial/modules.html#intra-package-references) in main modules. – x-yuri Jun 11 '17 at 21:05