Where to import dependency while working with multiple files - python-3.x

Let's say there are two files - mask.py and main.py.
mask.py has some function that I'm importing into main.py.
So if that function in mask.py which I'm importing has dependency like "os", where should I import os - in mask.py or main.py.

Let us consider a scenario as you have stated by using two files mask.py and main.py.
mask.py
import os
def some_function():
os.environ['a_url'] = "something.com" # using dependency as you mentioned
main.py
from mask import some_function
# do something with the function
Now, coming to your query, if you use import os in main.py but not in mask.py, you will get NameError in mask.py saying:
NameError: name 'os' is not defined
This is because you need to import any dependency in the same file where it is used. Also, if both of your file uses this dependency, you need to import it in both the files.
Hope this clarifies your query.

Related

Relative import doesn't work : ImportError: attempted relative import with no known parent package

This are the files:
parent_directory:
parent_directory/ecommerce:
parent_directory/ecommerce/payments:
What I'm trying to do is to use a relative import in products.py in order to import database.py. I know that I can just write import database but I want to learn relative imports. I've also tried to import main.py from the top level directory, parent_directory, but that doesn't work either so I thought I'll just try to do the easiest relative import possible and that is, importing a file from the same package.
This is the code for products.py inside parent_directory/ecommerce:
from .database import Database
class Product:
pass
And this is the code from the database.py file inside parent_directory/ecommerce:
if __name__ == "__main__":
import products
x = products.Product()
class Database:
pass
print("file : {0:<35} || name : {1:<20} || package : {2:<20}".format(
str(__file__).split("\\")[-1],
str(__name__),
str(__package__),
))
I tried several things like:
executing products.py with -m like python -m products.py
creating a py venv
adding all and package inside the files.
Here is my init.py file from parent_directory/ecommerce:
__all__ = ["database", "products"]
__package__ = "ecommerce"
No matter what I do, I always get this error: ImportError: attempted relative import with no known parent package. I know that this question has been asked before. I've tried many things out but nothing worked. Do you have any idea how to fix this ?
I found the solution to my problem.
I have to be outside the package and use -m and instead of using / to send the path, I have to use . instead so :
python -m parent_directory.ecommerce.products
This will fix the problem but I have to execute this line outside the top-level package ( in my case, the top level package is parent_directory ).
# Inside products.py
from .database import Database # works
from ..main import SomeRandomClass # works
class Product:
pass
I've found a way to import files from parent directories, since it's very easy to import them from sub-packages by using absolute imports.
# inside parent_directory/ecommerce/products.py trying to import parent_directory/main.py
import sys
import os
current_file = os.path.realpath(__file__)
current_dir_ecommerce = os.path.dirname(current_file)
parent_dir_parent_directory = os.path.dirname(current_dir_ecommerce)
sys.path.insert(0, parent_dir_parent_directory)
import main # works
I just added the parent directory to sys.path.

using class from different directory

[Python 3.5.2, Docker container]
I have a class BCM in a file called metrics.py which I would like to use in several Jupyter notebooks which are in different directories. When they are in the same file, the following obviously works from metrics import BCM. I would like it to work with the following directory structure.
experiments\
common\
__init__.py
metrics.py
exp1\
glm.ipynb
exp2\
gbm.ipynb
It works if I do the following
import os, sys
module_path = os.path.abspath(os.path.join('..'))
if module_path not in sys.path:
sys.path.append(module_path)
from common.metrics import BCM
Based on posts that I have seen here, it would seem that the following should work from ..common.metrics import BCM. I get the following error SystemError: Parent module '' not loaded, cannot perform relative import.
Is there a way to use that class without changing the path as shown above?

"No module named" when importing from another package in python3.6

If I execute demo2.py it works fine, the problem is when I execute main.py
|myPackage
|subPackage
demo.py
demo2.py
main.py
main.py
from ludikDriver.demo2 import demo2_print
demo2_print()
demo2.py
from demo import demoprint
def demo2_print():
print("demo2")
demoprint()
demo2_print()
demo.py
def demoprint():
print("demo")
Error:No module named 'demo'
Just use relative imports as suggested in pep 328.
from .demo import demoprint
You can do for the other package. Just as relative paths.
Your modules need context of themselves. You should have the "__init__.py" file in subPackage and myPackage. Then your import should be relative:
from . import demo
OR more in context of your example:
from .demo import demoprint
Your error is associated with the top line in demo.py:
from demo import demoprint
There is no module named demo

Python 3.5 - Smart module imports in the file tree

I was wondering if it was possible for modules in a project to be smart about their imports...
Say I have the following data structure :
/parent-directory
/package
__init__.py
main.py
/modules
__init__.py
one.py
/submodules-one
__init__.py
oneone.py
onetwo.py
two.py
Files higher in the hierarchy are supposed to import Classes from those lower in the hierarchy.
For instance main.py has
import modules.one
import modules.two
Now I'd like to be able to directly run not only main.py, but also one.py (and all the others)
Except that it doesn't work like I hoped :
If I run from main.py, I need to have in one.py
import modules.submodules-one.oneone
import modules.submodules-one.onetwo
But if I run from one.py, I'll get an error, and I need to have instead
import submodules-one.oneone
import submodules-one.onetwo
I've found a hacky way to get around it using in one.py :
if __name__ == '__main__':
import submodules-one.oneone
import submodules-one.onetwo
else:
import modules.submodules-one.oneone
import modules.submodules-one.onetwo
But isn't there a better solution?
P.S.: I also have an additional complication, I'm using pint,
which to work properly only needs to have a single instance of the unit registry, so I have in the top ____init____.py :
from pint import UnitRegistry
ur = UnitRegistry()
And obviously
from .. import ur
will fail if running from one of the files of the subfolders.
Thank you in advance for your answer.

Import csv from executed file raises error

I have a working python3 program that imports various standard library modules, e.g.
import re
import os
import csv
...
It runs without problem when I execute it directly. Now I want to run it through an exec call from an outside script, like this:
with open("main.py") as main:
exec(main.read())
But I get an error:
ImportError: no module named 'csv'
How can I make the executed script import all modules correctly?
I thought that all these three modules belong to the python standard library so, why the first two modules seem to be found while the third is not?

Resources