Python imports-Need someone to check this please - python

Ok yes it is a very silly question, but just that I am getting a little confused.
I have a file structure which looks like this:-
-Mainapplication
-models.py
-Helpingmodules
-Folder1
-module1.py
Now I have to import models into module1. So in module1.py I just did:-
from Mainapplication import models
Now this does work fine, but I get a feeling that it might be wrong. Can someone please let me know if this is the correct way.

There's nothing wrong with the import, but if the names of your packages are accurate, this looks like a design flaw in that you're destroying code reusability; I'd expect a package of "helping modules" to be independent of the application they're helping (although in the case the package name is so vague that I could be way off about their purpose.)

There's nothing wrong with your import.
You could say:
import Mainapplication.models
but then you'd have to reference models with its Package prefix every time you used it, e.g.:
Mainapplication.models.foo("bar")
The way you've done it allows you to use the following form which is usually preferable:
models.foo("bar")
For the full story you can read the documentation.

Related

relative import from utility script in subdirectory

From reading over other answers, it seems that possibly my layout is "un-Pythonic," although I'm really not quite sure. If so that would be helpful to know, along with a suggestion for the better layout.
Here is my script layout:
/
__init__.py
main_prog.py
utilities.py
/support_scripts
support_utility1.py
support_utility2.py
...
The support utilities contain functionality which are related to main_prog.py, but are best placed in their own scripts. Since there are many of them, I have moved them in their own directory. But they use some of the same functionality from utilities.py
When I try to import using from .. import utilities I get the error message "ValueError: attempted relative import beyond top-level package"
Now my first question would simply be: Is it considered bad to try to place additional scripts in subdirectories like this? Knowing a general principle like that would go a long way to solving my problems. And of course if you have any specific suggestions that will help too.

Is it possible to insert import statements with jedi-vim?

I've just started looking at the Vim jedi plugin, and it seems pretty impressive. One feature of some of the Java IDEs I've used is the ability to automatically add required imports. Can Jedi do that? For example, if I enter a line such as
arg1 = sys.argv[1]
and then invoke some Jedi command, is it possible for the plugin to automatically insert an import sys line at the top of the source file (if sys is not already being imported)?
I've looked through the Jedi help, and can't see anything like this - but it's possible I missed something. Alternatively, is there another Vim plugin that would do this? (It needs a certain level of understanding of Python syntax to get it right, which is why I looked to Jedi to be able to do it).
Currently Jedi doesn't do refactoringing. This includes import additions. There's an issue for the whole subject: https://github.com/davidhalter/jedi/issues/667.
It's not that easy to implement this command with good performance. However any help is appreciated. :)
FIY, I've defined a generic import feature that can be used on demand in lh-dev. I use it from my C&C++ suite, and from my snippet engine (mu-template).
So far I don't parse anything to add the missing import/include statements. This part would be complex as Dave said. Instead my snippets know which files need to be imported/included and import/include them if not already imported/included.
It's far from being perfect, but it's a start. mu-template provides a hook to do stuff at the start of the file after the snippet has been expanded, this is where I call lh-dev function. If other snippet engines provide similar hooks, you should be able to call lh#dev#import#add() from your snippets.
Here a proof of concept snippet for Python (I seldom program in Python, and don't have many snippets for it): https://github.com/LucHermitte/mu-template/blob/master/after/template/python/path-exists.template

Python: Calling a function from a file that has current file imported

I tried searching around but didn't seem to find an answer to my problem, so I'm sorry if I missed something and it actually has been answered before.
So basically I have main.py and another file called check.py (both in same directory)
In my main.py I have:
from check import checkfunction
I have a small function inside main.py that I MUST call inside check.py, but I can't seem to get this import working on my check.py:
from main import mainfunction
How can I get the mainfunction to work inside check.py?
Thanks!
You've got a design with a circular dependency which is usually a bad thing as your two python modules are tightly coupled.
Consider refactoring your code. But if you must stick with your design please see the following SO question for more info on how circular imports work in Python and the various gotchas to look out for.
Several options:
Move the common function to a module imported by both other modules.
Merge both modules into one.
Pass the function from main to the code that needs to call it.
Monkey patch the function into the check module after importing it.
Refactor the whole thing so that you don't have circular dependencies.
If you actually explained why you have this design, someone could possibly propose a better way.

Is it always a good idea to import very specifically in Python?

This is pretty much Python, but asking from a Django user.
Suppose this is how Django apps are layout:
Webclient
apps
myapp#1
library
library.py
myapp#2
views.py
myapp#3
If I am working with views.py, and I want to import library.py, which one seems better?
from webclient.apps.myapp.library import LibraryClass
from webclient.apps.myapp.library.library import LibraryClass
I am using PyCharm, and either way doesn't complain about "unresolved references".
Is it better to import very speifically. Is second import method more likely to avoid name collison, if possible at all (say /library/ has several .py files)?
Thanks.
You should always import names from where they're defined. That way if webclient.apps.myapp.library should stop importing LibraryClass one day, you won't break the other imports.
As a follow-up to Ignacio's answer, you should look at the documentation of the libraries you are using, to see where it suggests you import things. It may be that although LibraryClass is defined in webclient.apps.myapp.library.library, it is documented as being in webclient.apps.myapp.library, so at some point, it the definition might be moved there, or webclient.apps.myapp.library.oldversion, but still accessible from webclient.apps.myapp.library.

Why does mass importing not work but importing definition individually works?

So I just met a strange so-called bug. Because this work on my other .py files, but just on this file it suddenly stopped working.
from tuttobelo.management.models import *
The above used to work, but it stopped working all of a sudden, and I had to replace it with the bottom.
from tuttobelo.management.models import Preferences, ProductVariant, UserSeller, ProductOwner, ProductModel, ProductVariant
from tuttobelo.management.models import ProductMeta, ShippingMethods
I know the following is the better way of coding, however ALL of the models mentioned in models are used, so my question is, what possible reasons can wildcard stop working?
The error I got was that the model I was trying to import does not exist, only if I remove the wildcard and import the name of the model could I get it imported properly.
Thanks!
Maybe the models module has an __all__ which does not include what you're looking for. Anyway, from ... import * is never a good idea in production code -- we always meant the import * feature for interactive exploratory use, not production use. Specifically import the module you need -- use that name to qualify names that belong there -- and you'll be vastly happier in the long run!-)
There are some cases in Python where importing with * will not yield anything. In your example, if tuttobelo.management.models is a package (i.e. a directory with an __init__.py) with the files Preferences.py, ProductVariant.py, etc in it, importing with star will not work, unless you already have imported it explicitly somewhere else.
This can be solved by putting in the __init__.py:
__all__ = ['Preferences', 'ProductVariant', 'UserSeller', <etc...> ]
This will make it possible to do import * again, but as noted, that's a horrible coding style for several reasons. One, tools like pyflakes and pylint, and code introspection in your editor, stops working. Secondly, you end up putting a lot of names in the local namespace, which in your code you don't know where they come from, and secondly you can get clashes in names like this.
A better way is to do
from tuttobelo.management import models
And then refer to the other things by models.Preferences, models.ProductVariant etc. This however will not work with the __all__ variable. Instead you need to import the modules from the __init__.py:
import Preferences, ProductVariant, UserSeller, ProductOwner, <etc...>
The drawback of this is that all modules get imported even if you don't use them, which means it will take more memory.

Categories