__init__.py file selective import - python

In order to simplify my imports, I added the following code to my __init__.py:
from varro.algo.models.model import *
from varro.algo.models.fpga import *
from varro.algo.models.nn import *
so that I can do from varro.algo.models import ModelNN
If I want to import a different kind of model that doesn't require Tensorflow (as ModelNN does), I don't want to import it, as it takes a long time to load and may not be installed on all systems I'm working on.
However, importing from varro.algo.models import ModelFPGA loads Tensorflow, even though I never import ModelNN.
Is there a way I can simplify the imports without having to import ModelNN every time? (I figured I could just put the import statement for Tensorflow in the class itself, but I want a more robust solution.)

Related

ImportError attempted relative import with no known parent

Based on some answers I try to be more specific.
I want to import the print and the models AND code in my main.py
I know the question gets asked a lot, but still I could not figure out whats wrong with my code!
I have a project directory like this
-project
--__init__py
--main.py
--print.py
--requests
--__init__.py
--models.py
--code.py
i want to import from print.py and * from requests
Therefore I tried to add these lines in main.py
from . import print
#or
import print
#for requests I tried
import os.path
import sys
sys.path.append('./requests')
from requests import *
all of those lines cause the same ImportError attempted relative import with no known parent ,
using Python 39
anyone an idea where the problem is?
I am very confused that this seems not to work, was it possible in older versions?
You should definitely not be doing anything with sys.path. If you are using a correct Python package structure, the import system should handle everything like this.
From the directory structure you described, project would be the name of your package. So when using your package in some external code you would do
import package
or to use a submodule/subpackage
import project.print
import project.requests
and so on.
For modules inside the package you can use relative imports. When you write
i want to import from print.py and * from requests Therefore I tried
it's not clear from where you want to import them, because this is important for relative imports.
For example, in project/main.py to import the print module you could use:
from . import print
But if it's from project/requests/code.py you would use
from .. import print
As an aside, "print" is probably not a good name for a module, since if you import the print module it will shadow the print() built-in function.
Your main file should be outside the 'project'-directory to use that as a package.
Then, from your main file, you can import using from project.print import ....
Within the project-package, relative imports are possible.

Ways of Importing Modules in python

I am confused in the methodologies of importing Modules in Python and stumbled onto the following.
import pandas as pd
from pandas import *
Was Wondering how these two commands are different from one another?
In practice, a quick answer is that if you import several modules in which some of the functions may have the same name(let's say .addition()). By importing in the manner of:
import module1 as md1
import module2 as md2
you can call md1.addition() and md2.addition() without trouble.
But if you import it as
from module1 import *
from module2 import *
you will get confused when you call addition().
Besides, if you are not familiar with the module, you could accidentally define a function which has the same name in the imported module and overwrites it. So, I think from module import * should be avoided unless you have a reason for that.

Need to re-load libraries in Python, with Canopy

I am working on a python project with Canopy, using my own library, which I modify from time to time to change or add functions inside.
At the beginning of myfile.py I have from my_library import * but if I change a function in this library and compute again myfile.py it keep using the previous version of my function.
I tried the reload function :
import my_library
reload(my_library)
from other_python_file import *
from my_library import *
and it uses my recently changed library.
But if it is :
import my_library
reload(my_library)
from my_library import *
from other_python_file import *
It gives me the result due to the version loaded the first time I launched myfile.py.
Why is there a different outcome inverting the 3rd and 4th line ?
Without seeing the source code, it's hard to be certain. (For future reference, it is most useful to post a minimal example, which I suspect would be about 10 lines of code in this case.)
However from your description of the problem, my guess is that your other_python_file also imports my_library. So when you do from other_python_file import *, you are also importing everything that it has already imported from my_library, which in your second example, will override the imports directly from my_library (Since you didn't reload other_python_file, it will still be using the previous version of my_library.)
This is one out of approximately a zillionteen reasons why you should almost never use the form from xxx import * except on the fly in interactive mode (and even there it can be dangerous but can be worth the tradeoff for the convenience). In a python source file, there's no comparable justification for this practice. See the final point in the Imports section of PEP-8.

Why do these python import statements behave differently?

Consider the following python package:
/pkg
/pkg/__init__.py
/pkg/a.py
/pkg/b.py
The a and b modules both depend on each other, and so each must import the other -- a circular dependency. There appear to be 4 ways to perform this import statement.
Inside a.py:
import b
Inside b.py (I'm only using one of these import statements at a time):
import a
import pkg.a
from pkg import a
from . import a
These import statements are all syntactically different versions of the same import, and yet they don't all work the same. Trying to import pkg.a will produce different results.
import a
The first import style works without error; though it will fail in python3 or if absolute imports are specified, so I would rather not use a deprecated style.
import pkg.a
This also works, though it makes the code a bit more verbose, especially when there are additional subpackages.
from pkg import a
This fails. ImportError: cannot import name a
from . import a
This also fails with the same error.
Why are these import statements resulting in different behavior? It seems odd that the last two styles should fail, especially since they appear to be the preferred style going forward. I'm using python 2.7.
EDIT:
To test this create a test.py with the following code:
import pkg.a
EDIT:
Also, if you use the as syntax to try and shorten the imported symbol on an import statement that otherwise works, it will also fail, though it will be an AttributeError:
import pkg.a as a

Python Module Import: Single-line vs Multi-line

When importing modules in Python, what is the difference between this:
from module import a, b, c, d
and this
from module import a
from module import b
from module import c
from module import d
To me it makes sense always to condense code and use the first example, but I've been seeing some code samples out there dong the second. Is there any difference at all or is it all in the preference of the programmer?
There is no difference at all. They both function exactly the same.
However, from a stylistic perspective, one might be more preferable than the other. And on that note, the PEP-8 for imports says that you should compress from module import name1, name2 onto a single line and leave import module1 on multiple lines:
Yes: import os
import sys
No: import sys, os
Ok: from subprocess import Popen, PIPE
In response to #teewuane's comment (repeated here in case the comment gets deleted):
#inspectorG4dget What if you have to import several functions from one
module and it ends up making that line longer than 80 char? I know
that the 80 char thing is "when it makes the code more readable" but I
am still wondering if there is a more tidy way to do this. And I don't
want to do from foo import * even though I am basically importing
everything.
The issue here is that doing something like the following could exceed the 80 char limit:
from module import func1, func2, func3, func4, func5
To this, I have two responses (I don't see PEP8 being overly clear about this):
Break it up into two imports:
from module import func1, func2, func3
from module import func4, func5
Doing this has the disadvantage that if module is removed from the codebase or otherwise refactored, then both import lines will need to be deleted. This could prove to be painful
Split the line:
To mitigate the above concern, it may be wiser to do
from module import func1, func2, func3, \
func4, func5
This would result in an error if the second line is not deleted along with the first, while still maintaining the singular import statement
To add to some of the questions raised from inspectorG4dget's answer, you can also use tuples to do multi-line imports when folder structures start getting deeply nested or you have modules with obtuse names.
from some.module.submodule.that_has_long_names import (
first_item,
second_item,
more_imported_items_with_really_enormously_long_names_that_might_be_too_descriptive,
that_would_certainly_not_fit,
on_one_line,
)
This also works, though I'm not a fan of this style:
from module import (a_ton, of, modules, that_seem, to_keep, needing,
to_be, added, to_the_list, of_required_items)
I would suggest not to follow PEP-8 blindly. When you have about half screen worth of imports, things start becoming uncomfortable and PEP-8 is then in conflicts with PEP-20 readability guidelines.
My preference is,
Put all built-in imports on one line such as sys, os, time etc.
For other imports, use one line per package (not module)
Above gives you good balance because the reader can still quickly glance the dependencies while achieving reasonable compactness.
For example,
My Preference
# one line per package
import os, json, time, sys, math
import numpy as np
import torch, torch.nn as nn, torch.autograd, torch.nn.functional as F
from torchvision models, transforms
PEP-8 Recommandation
# one line per module or from ... import statement
import os
import json
import time
import sys
import math
import numpy as np
import torch
from torch import nn as nn, autograd, nn.functional as F
from torchvision import models, transforms
A concern not mentioned by other answers is git merge conflicts.
Let's say you start with this import statement:
import os
If you change this line to import os, sys in one branch and import json, os in another branch, you will get this conflict when you attempt to merge them:
<<<<<<< HEAD
import os, sys
=======
import json, os
>>>>>>> branch
But if you add import sys and import json on separate lines, you get a nice merge commit with no conflicts:
--- a/foo.py
+++ b/foo.py
### -1,2 -1,2 +1,3 ###
+ import json
import os
+import sys
You will still get a conflict if the two imports were added at the same location, as git doesn't know which order they should appear in. So if you had imported time instead of json, for example:
import os
<<<<<<< HEAD
import sys
=======
import time
>>>>>>> branch
Still, it can be worth sticking with this style for the occasions where it does avoid merge conflicts.
Imports should usually be on separate lines as per PEP 8 guidelines.
# Wrong Use
import os, sys
# Correct Use
import os
import sys
For more import based PEP 8 violations and fixes please check this out https://ayush-raj-blogs.hashnode.dev/making-clean-pr-for-open-source-contributors-pep-8-style.
Both are same.
Use from module import a, b, c, d.
If you want to import only one part of a module, use:
from module import a
If u want to import multiple codes from same module, use:
from module import a,b,c,d
No need to write all in separate lines when both are same.

Categories

Resources