How do I import symbols inside a Python package? - python

I have three database-related classes that I want to combine into a package, in the following structure:
adodb_pyodbc /
__init__.py # empty
PyConnection.py
PyRecordset.py
PyField.py
This package is in my Lib/site-packages folder.
In an earlier iteration of this attempt, I did not use the "Py" prefix, and I got an error complaining that module.__init__() takes only two arguments, and three were being passed into it. Someone suggested that the name "Recordset" might be conflicting with something else, so I changed it.
The classes work when the files are in the same folder as the project that is using them. In that case, I can just use:
PyRecordset.py:
from PyConnection import PyConnection
from PyField import PyField
class PyRecordset: pass
DerivedSet.py
from PyRecordset import PyRecordset
class DerivedRecordset(PyRecordset): pass
But the same files don't work when they are located inside a package. My test program begins with this line:
from adodb_pyodbc import PyConnection as Connection
And when I run it I get this error message:
C:\Python35\python.exe "C:/Customers/Nucor Crawfordsville/Scripts/64 bit/Testing/cpsa_simulator.py"
Traceback (most recent call last):
File "C:/Customers/Nucor Crawfordsville/Scripts/64 bit/Testing/cpsa_simulator.py", line 8, in <module>
from Level3_CoilsSet import Level3_CoilsSet
File "C:\Customers\Nucor Crawfordsville\Scripts\64 bit\Testing\Level3_CoilsSet.py", line 1, in <module>
from adodb_pyodbc import PyRecordset as Recordset
File "C:\Python35\lib\site-packages\adodb_pyodbc\PyRecordset.py", line 9, in <module>
from PyConnection import PyConnection
ImportError: No module named 'PyConnection'
But when editing PyRecordset.py inside PyCharm, it appears to be able to find the PyConnection.py file.
I tried using relative addressing inside PyConnection.py:
from . import PyConnection
from . import PyField
But that puts me back to the __init__() error:
C:\Python35\python.exe "C:/Customers/Nucor Crawfordsville/Scripts/64 bit/Testing/cpsa_simulator.py"
Traceback (most recent call last):
File "C:/Customers/Nucor Crawfordsville/Scripts/64 bit/Testing/cpsa_simulator.py", line 8, in <module>
from Level3_CoilsSet import Level3_CoilsSet
File "C:\Customers\Nucor Crawfordsville\Scripts\64 bit\Testing\Level3_CoilsSet.py", line 3, in <module>
class Level3_CoilsSet(Recordset):
TypeError: module.__init__() takes at most 2 arguments (3 given)
How am I supposed to do this?
Thanks very much for your help. In the meantime, I'm going to take those files out of the package and put them back in my test project. I've wasted far too much time on this question.

When you one to use PyConnection from outside of the package you have to either import it from the module where it was defined:
from adodb_pyodbc.PyConnection import PyConnection as Connection
Or, more conveniently, import it in the package init file adodb_pyodbc/__init__.py:
from .PyConnection import PyConnection
And then, from the outside, you can just do:
from adodb_pyodbc import PyConnection as Connection

Related

I can not figure out why I can not start this simlple python script

My directory looks like this
When I start directly with PyCharm it works.
But when I try to start the script with a commandline I get this error messsage
> python .\PossibilitiesPlotter.py
Traceback (most recent call last):
File "C:\Users\username\PycharmProjects\SwapMatrixPlotter\possibilitiesplotter\PossibilitiesPlotter.py", line 7, in <module>
from plotterresources.PlotterProps import PlotterProps
ModuleNotFoundError: No module named 'plotterresources'
This is how the import looks from my main class PossibilitesPlotter.py
import sys
sys.path.append("plotterresources/PlotterProps.py")
from csv import reader
from pathlib import Path
from plotterresources.PlotterProps import PlotterProps
from possibilitiesplotter.PossibilitiesGraph import PossibilitiesGraph
from possibilitiesplotter.PossibilitiesModel import PossibilitiesModel
class PossibilitiesPlotter:
As a workaround, add the following line to PossibilitesPlotter.py:
sys.path.append("../plotterresources/PlotterProps.py")
This will add the directory one level above the commandline pwd to the PATH variable. So this is always relative to the location of the calling script/shell.
Thus in general:
NEVER append to the PATH/PYTHONPATH variable from within modules. Instead restructure your module. For more details, take a look at the documentation on Packaging Python Projects

python: from x import isn't work in directory

my files are look like this
-root/
-main.py
-nyaizhel_includes/
-includemain.py
-commands/
-astolfo.py
-naruto.py
...
from main.py, i import includemain.py
from nyaizhel_includes import includemain
it works, includemain.py gets imported,
from includemain.py i import commands
from commands import astolfo
from commands import narutobanner
from commands import rgirl
...
includemain.py gets included but astolfo isn't get included, why?
console log
heroku[main.1]: State changed from starting to up
2021-04-13T09:42:02.840988+00:00 app[main.1]: Traceback (most recent call last):
2021-04-13T09:42:02.841010+00:00 app[main.1]: File "/app/main.py", line 42, in <module>
2021-04-13T09:42:02.841140+00:00 app[main.1]: from nyaizhel_includes import includemain
2021-04-13T09:42:02.841141+00:00 app[main.1]: File "/app/nyaizhel_includes/includemain.py", line 1, in <module>
2021-04-13T09:42:02.841258+00:00 app[main.1]: from commands import astolfo
2021-04-13T09:42:02.841262+00:00 app[main.1]: ModuleNotFoundError: No module named 'commands'
2021-04-13T09:42:02.950174+00:00 heroku[main.1]: Process exited with status 1
2021-04-13T09:42:03.023470+00:00 heroku[main.1]: State changed from up to crashed
You didn't list your __init__.py file in your example, so make sure you add those so these are recognized as standard packages (although it seems you may already have).
The source of your error is likely that you're trying to do a relative import but specifying an absolute import:
If you use from .commands import astolfo (notice the period to signify relative import), that should resolve your issue. It is recommended to use absolute imports as per the PEP 8 Style guide however. In your case this would be from nyaizhel_includes.commands import astolfo, assuming nyaizhel_includes is your root package here.
See the documentation on Python packages for more information.

A very simple question on python import, functions, sub-directories

I have a super simple python project, but I can't get it to work.
In the directory called "demo", I have a file called "demo.py", reading:
#!/usr/bin/python
from calc import plus
print(plus(1, 4))
I also have a sub-directory called "calc" with the following files:
__init__.py
minus.py
plus.py
The init.py is empty, whereas "minus.py" and "plus.py" read respectively:
def minus(a, b):
return a - b
and
def plus(a, b):
return a + b
When I run the demo.py, I get the error:
Traceback (most recent call last):
File "./demo.py", line 3, in <module>
print(plus(1, 4))
TypeError: 'module' object is not callable
It must be something absurdly simple, but I just can't figure it out.
Any help and advice would be highly appreciated.
Cheers
You need fix your import.
You have a file and one function with same name, then you need import the module(file) and after import the function.
from calc.plus import plus
Or custom your init.py
https://docs.python.org/3/tutorial/modules.html

ImportError: cannot import module

The package looks like this:
main.py
HTTPQuery.py
SmartDownload.py
in main.py I run from SmartDownload import DownloadFile.
in Smartdownload.py I run from HTTPQuery import Is_ServerSupportHTTPRange
in HTTPQuery I run from SmartDownload import DownloadFile
It seems that I get stuck in a loop, because this is the error:
Traceback (most recent call last):
File "C:\Scripts\mp3grabber\main.py", line 13, in <module>
import HTTPQuery
File "C:\Scripts\mp3grabber\HTTPQuery.py", line 6, in <module>
from SmartDownload import DownloadFile
File "C:\Scripts\mp3grabber\SmartDownload.py", line 3, in <module>
from HTTPQuery import Is_ServerSupportHTTPRange
ImportError: cannot import name Is_ServerSupportHTTPRange
But I must import second file's functions into the third file and vice-versa.
What can I do?
As you suggest, there is a circular dependency between HTTPQuery and SmartDownload. The easy fix is to move the import into the functions that require it, e.g.
# SmartDownload.py
def download(url):
from HTTPQuery import Is_ServerSupportHTTPRange
...
A better solution might be to reorganize your modules. If there is no reasonable way to remove HTTPQuery's dependence on SmartDownload or vice versa, consider merging them into one module.
Your best option is to re-organize the dependencies so you don't have this circular import problem. Barring that, you may be able to simply move the line from SmartDownload import DownloadFile to the bottom of your HTTPQuery.py file to break the loop.
There's a bit of discussion on circular imports here.

Python Wildcard Import Vs Named Import

Ok, I have some rather odd behavior in one of my Projects and I'm hoping someone can tell me why. My file structure looks like this:
MainApp.py
res/
__init__.py
elements/
__init__.py
MainFrame.py
Inside of MainFrame.py I've defined a class named RPMWindow which extends wx.Frame.
In MainApp.py this works:
from res.elements.MainFrame import *
And this does not:
from res.elements.MainFrame import RPMWindow
I realize that the wild card import won't hurt anything, but I'm more interested in understanding why the named import is failing when the wild card succeeds.
When using the class name I get this traceback:
Traceback (most recent call last):
File "C:\myApps\eclipse\plugins\org.python.pydev.debug_1.5.6.2010033101\pysrc\pydevd.py", line 953, in <module>
debugger.run(setup['file'], None, None)
File "C:\myApps\eclipse\plugins\org.python.pydev.debug_1.5.6.2010033101\pysrc\pydevd.py", line 780, in run
execfile(file, globals, locals) #execute the script
File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\MainApp.py", line 2, in <module>
from res.elements.MainFrame import RPMWindow
File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\res\elements\MainFrame.py", line 2, in <module>
from res.elements.MenuBar import MenuBarBuilder
File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\res\elements\MenuBar.py", line 2, in <module>
from MainApp import _, DataCache
File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\MainApp.py", line 2, in <module>
from res.elements.MainFrame import RPMWindow
ImportError: cannot import name RPMWindow
When using the wild card import I don't receive a traceback and my application opens.
You have circular imports:
MainFrame.py is indirectly importing MainApp.py, and MainApp.py is importing MainFrame.py. As a result, when MainApp.py is importing MainFrame.py, the RPMWindow class hasn't been defined yet and you get the ImportError.
i don't have time to look into why the wildcard is working for you, but what i can say about your failure with the direct name import is that you have an import cycle in your code:
you are trying to import res.elements.MainFrame, but part of that code is trying to import res.elements.MenuBar which tries to import res.elements.MainFrame again. IOW, your first attempt to import res.elements.MainFrame has not completed yet before you try it again.
You have circular imports in your code: the same module is both required by and requires the use of a certain other module, which when you think of it like that, it clearly precarious. Most of the problems can be cleared up by using import a and later referring to a.b instead of from a import b or from a import *.
In particular, never use from a import *. Wildcard imports clutter your namespace and makes your code less maintainable, readable, sane, and predictable. The difference between import a and from a import * is the difference between dragging a box into a room and pouring its contents all over the floor.
It would be better if you could move shared code off to its own module or somehow refactor out the need for a circular import. Circular imports always indicate a design problem.

Categories

Resources