What is the right way to create project structure in pycharm? - python

I'm new to python and I don't know how to organize the project structure in the right way, so all auto imports would work in pycharm.
That's my current structure.
In PublisherSubscriberTest pycharm generated this import
from Rabbit.RabbitReceiver import RabbitReceiver
from Rabbit.RabbitSender import RabbitSender
But it's not working. That's the output.
ImportError: No module named Rabbit.RabbitReceiver
What have I done wrong?
I'm more familiar with java. And for example in java I would just create package with some classes and then I would be able to import them anywhere in my project. AFAIK it's not the same with python somehow.
Could someone explain this to me?
EDIT1:
Yes, I know about sys.path.append. I used to do it that way, but It seemed strange to me and i want to be able to do it without it.

import sys, os.path
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
from Rabbit.RabbitReceiver import RabbitReceiver
from Rabbit.RabbitSender import RabbitSender
If you don't want to modify sys.path, the only way is to add -m flag when you run it
python -m messaging_system.tests.PublisherSubscriberTest
see How to fix "Attempted relative import in non-package" even with __init__.py
edit
OK, finally I found an ultimate answer: Relative imports for the billionth time
I suggest you read that post carefully, from which I learned a lot.
In short, if you want to do this, you have to add path-to-Rabbit to sys.path.

Related

Attempted relative import with no known parent package - cannot import python file from parallel dictionary

That's my project's structure
I'm trying to run stock_tracker_app.py, but I got the
"ImportError: attempted relative import with no known parent package"
There is problem within my second import.
import APIRequestFinnhub
from .. import stock_database
What should I do? I don't wanna waste time with messing up with my local database and moving everything into one dictionary. Please help me, at this point I really don't know how imports in python works. It scares me.

Importing module/package from sister folder. Python 3.3, along with VSCode

Here's my hierarchy (note __init__.py is not needed in 3.3+):
SomeFolder/
/SomePackage
SomeModuleA.py
SomeModuleB.py
/SomeSmallProject
SomeLogic.py
SomeResource.bmp
Within SomeLogic.py I want to import the modules contained in /SomePackage
I've been doing this with import sys; sys.path.insert(0, ".."), and this works. However I know it's hacky and I don't like it. Is there any other way of doing this properly? (other than editing PYTHONPATH)
Additionally, I cannot get VSCode to properly pylint and import using this method. So bonus points for anyone who can help me with that as well. Specifically VSCode does not update its search path after the sys.path.insert() hack.

Import a library from parent directory | python

I want to import a library in parent directory, the structure of the folder looks like:
So, how i can import this lib?
I'd suggest you read about how python handles imports. It's not a proper way to structure your package. You may grunge over it a bit, but it's the only way to stay concious about your structure and dependencies. Otherwise you'll have a mess like in C#, where vs-studio just imports everything from everywhere.
You can add the parrent Directory to sys.path, but this is not the way how this should be do.
Make lib a package(add __init__.py file in the folder) and then from lib import library.
There are several solutions to this problem.
A simple and straight forward one would be to add the path to your library. This solution is useful in case you are prototyping, and you don't want to make an actual package yet.
import sys
sys.path.insert(0, "/path/to/your/package_or_module")
Then you can go on with import my_package.
Here is one example.
➜ cat Desktop/folder_X/my_package.py
hello = 'Hi there!'
➜ cat Desktop/folder_Y/run.py
import sys
sys.path.insert(0, '/Users/xxx/Desktop/folder_X')
from my_package import *
print(hello)
➜ python Desktop/folder_Y/run.py
Hi there!
A better way, in general, is to make a proper package. It requires a bit more knowledge, but it worths the effort. Please, read the docs on that.

Python import modules issue

I recently was asked to deliver a python project as part of an interview process.
I tested my project on Windows and MacOSX, with Pycharm, Spyder, jupyter notebook and command line and everything works fine.
However, the reviewer was unable to make the project work on his side, because of module import issues according to him.
My modules are organized like this:
my_project/
my_module.py
main_module.py
my_package/
__init__.py
my_submodule_1.py
my_submodule_2.py
my_submodule_1.py:
import my_module
import my_submodule_2
I haven't added any path related to this project in PYTHONPATH.
The project main function is located in main_module.py.
The reviewer seem to have problems with the modules imported in my_submodule_1.py.
Could anyone shed some light on possible mistakes here and why it would work on my side and not on his?
Your my_submodule_1 module is doing an implicit relative import when it imports my_submodule_2 directly.
That's not legal in Python 3. It is allowed in Python 2, though its usually a bad idea to use it. You can get the Python 3 semantics by putting from __future__ import absolute_import above the other import statements in your file. To fix the import, you'd want to change import my_submodule_2 to either import my_package.my_submodule_2 (an absolute import) or from . import my_submodule2 (an explicit relative import).
If your interviewer is using Python 3 and you're using Python 2, there are likely to be other issues with your code (especially if you're doing any sort of text processing), so I'd make sure you're testing your code in the version they expect!
I think since my_module.py is not in same directory as my_submodule1.py ,and on the reviewer pc the sys.path doesn't have that location of my_module.py, that's why it getting problem in importing the module from its parent directory.
if u give the details of error that the reviewer is getting it might help finding the right solution.

Including xlrd/xlwt/xlutils with modules outside of python installation

I'm self-taught in the Python world, so some of the structural conventions are still a little hazy to me. However, I've been getting very close to what I want to accomplish, but just ran into a larger problem.
Basically, I have a directory structure like this, which will sit outside of the normal python installation (this is to be distributed to people who should not have to know what a python installation is, but will have the one that comes standard with ArcGIS):
top_directory/
ArcToolbox.tbx
scripts/
ArcGIStool.py (script for the tool in the .tbx)
pythonmod/
__init__.py
general.py
xlrd/ (copied from my own python installation)
xlwt/ (copied from my own python installation)
xlutils/ (copied from my own python installation)
So, I like this directory structure, because all of the ArcGIStool.py scripts call functions within the pythonmod package (like those within general.py), and all of the general.py functions can call xlrd and xlwt functions with simple "import xlrd" statements. This means that if the user desired, he/she could just move the pythonmod folder to the python site-packages folder, and everything would run fine, even if xlrd/xlwt/xlutils are already installed.
THE PROBLEM:
Everything is great, until I try to use xlutils in general.py. Specifically, I need to "from xlutils.copy import copy". However, this sets off a cascade of import errors. One is that xlutils/copy.py uses "from xlutils.filter import process,XLRDReader,XLWTWriter". I solved this by modifying xlutils/copy.py like this:
try:
from xlutils.filter import process,XLRDReader,XLWTWriter
except ImportError:
from filter import process,XLRDReader,XLWTWriter
I thought this would work fine for other situations, but there are modules in the xlutils package that need to import xlrd. I tried following this advice, but when I use
try:
import xlrd
except ImportError:
import os, sys, imp
path = os.path.dirname(os.path.dirname(sys.argv[0]))
xlrd = imp.load_source("pythonmod.xlrd",os.path.join(path,"xlrd","__init__.py"))
I get a new import error: In xlrd/init.py, the info module is called (from xlrd/info.py), BUT when I use the above code, I get an error saying that the name "info" is not defined.
This leads me to believe that I don't really know what is going on, because I thought that when the init.py file was imported it would run just like normal and look within its containing folder for info.py. This does not seem to be the case, unfortunately.
Thanks for your interest, and any help would be greatly appreciated.
p.s. I don't want to have to modify the path variables, as I have no idea who will be using this toolset, and permissions are likely to be an issue, etc.
I realized I was using imp.load_source incorrectly. The correct syntax for what I wanted to do should have been:
imp.load_source("xlrd",os.path.join(path,"xlrd","__init__.py"))
In the end though, I ended up rewriting my code to not need xlutils at all, because I continued to have import errors that were causing many more problems than were worth dealing with.

Categories