What is the good way to deal with python import? [duplicate] - python

This question already has answers here:
Can't import my own modules in Python
(14 answers)
Closed 2 years ago.
I am working in python3 for a year now and I still don't get the import system....
I always put the empty init.py file on each folder.
But however if my project start to have nested directories (and it append a lot and often) I have to run a war to be able to import my own module (who python thinks he is ????)... It is driving me crazy.
So for now the 'best' trick I have found, but clearly I am not satisfied with it is to put ligne like this on top of my file:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(file))))
I do not like it, first because when the directory is nested on several level the line is extraordinary long, then because my linter is always yelling at me because my import are not on top of my files.
So I was wondering, what am I missing ? Is there an information I missed ? What's your technique ?
Thank you !
Can't import my own modules in Python
Someone suggested it's similar to this answer but it is not.
First I do not want to use relative import.
Then the 'sys.path.append("..")' is not clean in my opinion, and my imports are still not on top of my files.
Basically let's say I have a structure like:
folder_a
----file_1
----file2
----folder_b
--------file_3
--------folder_c
-----------file_4
I am instanciating a class from file_1 in file_3,I have to do this:
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(file)))))
from folder_a.file_1 import class_1
doing this obviously won't work:
sys.path.append("..")
from folder_a.file_1 import class_1
This is so not logic for me

If you don't want to use relative imports, and you don't want to mess with sys.path, the other option is to package your modules and install them using pip install.
I think that reading the import documentation instead of just trying to "make it work" will be beneficial. Python's documentation is really good. Focus for a while with a good cup of tea and read it :)

Related

Unused import statement: classic problem while importing own module

OK, prerequisites:
It's my first ever Python project. I used to do some scripting but never anything bigger
So I'm at the very beginning of a learning curve. It's like when you can't kill an ant in Fallout 2 Temple level. On later levels, I was really good in Fall 2:)
Problem:
I can't figure out how to import a module written by me and placed in a different folder
Context:
The project I'm intended to create is meant to do a lot of measures conversions. So I decided to store in DB all data in the same unit system & keep all conversions upon user preferences on a codebase level
In a different folder I decided to store tests. To write the very first one (testing the abovementioned module) I need to import the module, but here is the story begins. I know it's classic, but I'm completely messed with import
Toolkit:
PyCharm Pro (PyCharm 2021.3.1)
Python 3.7 interpreter
macOS 10.15, Intell
Set up:
Settings screenshot provided
Project structure. Folders are marked as Source & Test
I need to import from conversions.py to test_conversions.py
PYTHONPATH settings like this
What do I, for the sake of God, need:
with all the abovementioned, how do I import conversions.py to test_conversions.py or any other place of my project? I read a number of articles and it's getting me anywhere (contradictory, 2.x related, etc). I feel like I need a piece of more foundational info but as well I need a clear walkthrough, a code snippet to import bloody file, I really appreciate any kind of advice
imports are a bit tricky. The issue you have is where your python is looking for packages. I would discourage you to add to your PYTHONPATH a specific project but you could do that locally in your file.
A much easier way is just to launch your test file from the top directory.
In this case your import will just be import conversion.conversion
And then you can launch your test from the root folder with python -m tests.conversion.
In Pycharm you can use the interface to deal with that, see this link. But I like the python -m because it works from anywhere, not only inside Pycharm.
make a class inside a conversion.py, then you can import it from test_conversion.py.
conversion.py
class convert():
def km_to_mm(input):
output = input * 1000000
return output
then import it in test_conversion.py
input = 0.001 # specify your input value
from conversion import convert
converted = convert().a_to_b(input)
converted will have value 1000
make sure you use the same folder. otherwise should use folder name to import. like
import foldername.conversion
from foldername.conversion import convert
I really appreciate all of you who tried to help. I got the problem solved in a very ridiculous manner, below is to someone who might face the same issue in the future.
So, in case you see the next:
You use PyCharm (no idea how other IDEs behave)
You created a module & want to import it into other files of your project
You type import module_name
While you type it, the string looks active and autocomplete even proposes you your module name but as only you finished typing, the import string turns grey, PyCharm throws you a warning saying Unused import statement, yellow bulb next to the import string suggests you delete the import string
--> This does not mean you are not able to import your module, it means you've done it and now can call anything from your module in the code below.
This taught me to pay some more time to read docs before jumping to using anything new and think better about UX in anything I do.

How to properly import a Python package in PyCharm? [duplicate]

This question already has answers here:
Why import when you need to use the full name?
(8 answers)
Closed 1 year ago.
I'm new to PyCharm, and after downloading a Python package (Manim) my code won't recognize the methods used in the package, unless I very precisely tell it where to look. In other words, when trying to just import Manim, I get this:
where PyCharm even seems to indicate that it doesn't need the two gray lines, as it has already imported Manim. The problem is the errors (underlined in red), they point to classes and/or methods from the Manim package, but are not recognized until I precise:
How can I optimize my imports so that one line suffices for all that's concerning Manim? (This works fine with just from manimlib import * using Spyder3 editor.)
As #Mike Scotty pointed out in his comments, import * and from a import * are generally bad ideas, since python won't know what to import, especially if there are multiple classes with the same name.
An IDE not complaining does NOT mean, your code runs smoothly.
You have several options here:
Having a rather large import list (which is by no means wrong) as you have in your second picture.
Using import manimlib and having rather long function/class calls: intro_words = manimlib.mobject.svg.text_mobject.Text
It's possible to bunch similar imports together like this:
from manimlib.mobject import geometry.Polygon as Polygon, svg.text_mobject.Text as Text
To my humble knowledge, the most pythonic way to go, is having very specific imports, even if that means you'll end up with a large import list. To add to this, most IDEs like PyCharm, Atom or Visual Studio have ways collapsing large import lists into one line:
for example PyCharm does this: import ... which displays all imports by clicking on it.
Refer to pythons documentation on imports and pythons documentation on modules to get a better understanding on how imports work.

How to structure a python package made of multiple sub-projects?

what is the correct way to structure a python package for multiple functionalities?
I have a case where my project can be broken into 3 completely separate, logical chunks that are entirely decoupled. As such, I have broken the sub-projects into respective folders in my python package project. This has led to a file structure like this;
foobartoo
|_setup.py
|_foobartoo
|_foo
| |_foo.py
|
|_bar
| |_bar.py
|
|_too
|_too.py
This method keeps things together but separate nicely, but after installing I have noticed a definite problem. The only way to access one of the files is to do
from foobartoo.foo.foo import <method/class>
or
import foobartoo.foo.foo as <something>
<something>.<method/class>
This seems extremely impractical.
I can see two alternatives
scrapping the folder system and having foo.py, bar.py and too.py in the same directory under foobartoo.
This seems bad because it will be impossible to know which file/code belongs to which of the projects
breaking the single package into multiple packages.
This seems ok, but it would be better if the 3 things were together as they are intended to be used together.
I have looked at numpy and its source code, and somehow they seem to have a lot of their functionality behind many folders, yet they dont need to reference any of the folders. This seems ideal, just being able to do something like
import foobartoo
foobartoo.<classname/methodname>()
You can add additional paths to your 'main' script so sys will search automatically to many directories like:
import sys
sys.path.append(example_sub_dir)
import sub_script
sys.path.remove(example_sub_dir)
!note that you can add many directories on sys to search but you need to care as import time will be rise respectivelly

Transition from MATLAB to Python [duplicate]

This question already has answers here:
Import folder of modules in Python
(3 answers)
Closed 7 years ago.
I know this question has been asked before but I can't make heads or tails of what the answer means.
I am making the transition from MATLAB to Python. In MATLAB I can write my own functions and use them in my code. I know I can do the same thing in Python. But I am having a hard time figuring out how to do it.
What I would like to do it create a file with multiple function definitions and then import it into Python like any other module.
First, is this the proper way of thinking it about it? Or do I just need to create multiple definition files for each function?
Second, if it is the proper way of thinking about it how do I access the file? I know you have to set the PYTHONPATH. I have looked at it and where it is looking makes no sense to me.
As an Example: I created a folder called User. In it I have a python function called ted.py. I put said file where the rest of the library files are located (as in numpy or scipy). I want to import the file called User. How can I do this?
After working with Python for awhile I get it. As long as the file is in the same directory and you use the import properly you can use one , some or all of the function definitions in the file.
You have an un-matlab-like (matlab-unlike? dis-matlab-like?) option of putting multiple function definitions into the same .py file. Once the file -- say, fundefs.py -- is on your path, possibly through having issued import sys; sys.path.append('path/to/fundefs');, you can import it
through import fundefs, after which you can access the functions therein by fundefs.fun1, fundefs.fun2 etc.
through from fundefs import *, which will throw all the functions into your current namespace. This is generally discouraged (and frowned upon) for larger modules as it will pollute your namespace, but for a few functions of your own this might just be what you're after. See also this very informative answer (and also comments therein).
as a middle ground through import very_long_and_descriptive_module_name as shorthand to access your functions as shorthand.fun1, shorthand.fun2 etc. (in the obvious case if your definitions are in the file very_long_and_descriptive_module_name.py)
You don't import User. What you want is to import ted. Typically, you would put ted.py in the same folder as your main python file, not in a separate folder.

can't import import datetime in script [duplicate]

This question already has answers here:
Importing installed package from script with the same name raises "AttributeError: module has no attribute" or an ImportError or NameError
(2 answers)
Closed 4 years ago.
I cannot import datetime from a python script, but I can from the terminal command line.
1)import datetime
2)From datetime import datetime
month = datetime.datetime.now().strftime("%B")
print month
These lines of code work when entered one by one into the command line
Any ideas?
I'm running 2.7 on mac
You named your script datetime.py, located at /Users/ripple/Dropbox/Python/datetime.py. This is being imported instead of the standard library module, because the directory of the main script is the first place Python looks for imports.
You cannot give your scripts the same name as a module you are trying to import. Rename your script. Make sure you also delete the bytecode cache at /Users/ripple/Dropbox/Python/datetime.pyc.
Here is what is happening:
you named your file datetime.py for testing
then you wrote import datetime inside it, because that's the module you want to try out
What happens when you run the file, is that:
Python first looks into your local directory for a module called datetime
Since Python only finds your original file, it makes an empty module file called datetime.pyc, because it expects you to build upon it
Luckily, the nice people at StackOverflow made you aware of this naming error, and you renamed your datetime.py file to something else. But confusingly you still get errors and the frustration slowly builds...
Solution:
Always make sure that your filenames aren't equal to any Python module you want to import
If you still forget, then make sure to delete or rename both the local .py script and the local .pyc file. This should fix your problem. :)
The reason this is such a common error, is that people like testing stuff when programming. And when they do, the natural inclination of most people is to make a script with the same name as the thing they want to test. However that's one of the first gotchas most Python developers run into. If the cool people that designed Python read Donald Norman before making their system, this would never be a problem. But as it is, we just have to adjust to how the Python module system works before naming our files. Note: There are still reasons for the Python module system working this way, however that doesn't preclude it from being confusing to beginners.
Your second line is overwriting what python understands the word 'datetime' to mean in later code. You should either use
import datetime # the complete module
month = datetime.datetime.now().strftime("%B")
or
from datetime import datetime # one part of the main module
month = datetime.now().strftime("%B")
while saving the scripts make sure you give it different name (other than date time) and save it in c:/Python34/Scripts; i' m sure this will work then.

Categories