Import * include submodules - python

I have a directory structure that looks like this:
scripts/
__init__.py
filepaths.py
Run.py
domains/
__init__.py
topspin.py
tiles.py
hanoi.py
grid.py
I would like to say:
from scripts import *
and get the stuff that is in filepaths.py but also get the things that are in hanoi.py
The outer __init__.py contains:
__all__ = ['filepaths','Run','domains','hanoi']
I can't figure out how to get the inner files to be included in that list. Putting hanoi by itself gets this error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'hanoi'
Putting domains.hanoi gets this error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'domains.hanoi'
The last reasonable guess I could come up with is putting scripts.domains.hanoi which gets this error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'scripts.domains.hanoi'
How do you get the all list to include things that are in subdirectories?

In scripts/__init__.py, before the __all__ add the following
from domains import topspin, tiles, hanoi, grid
This will add those modules to the namespace, and you will be able to import them with
from scripts import *
Note
As a soapbox, it is preferred to do things like
from scripts import topspin, tiles, hanoi, grid, filepaths, Run
over
from scripts import *
because 6 months from now, you might look at hanoi on the 400th line of code and wonder where it came from if you use the * import style. By explicitly showing what is imported from scripts it serves as a reminder where things come from. I'm sure that anyone trying to read your code in the future will thank you.

Import them first, in the __init__ files.
In scripts/__init__.py, import at least domains, and in scripts/domains/__init__.py import hanoi, etc. Or import domains.hanoi directly in scripts/__init__.py.
Without importing these, the scripts/__init__.py module has no reference to the nestend packages.

Related

partially initialized module 'router' has no attribute 'FindCorrectRoute' (most likely due to a circular import)

I try to call from main.py a function in router.py that will call a function in calculator.py that will try to modify a variable in main.py
Something that in C# is achieved for example by creating a public static variable, I don't know how to achieve it in Python.
This is my file main.py:
import router
# create a table
global mytable
mytable = []
router.CallAnotherFunction("testing data")
This is my file router.py:
import calculator
def CallAnotherFunction(sample_data):
calculator.ModifyMainTable(sample_data)
This is my calculator.py:
import main
def ModifyMainTable(sample_data):
main.mytable = sample_data
This is the error I'm getting just when trying to execute router.CallAnotherFunction("testing data"):
AttributeError
partially initialized module 'router' has no attribute 'FindCorrectRoute' (most likely due to a circular import)
File "C:\Users\dimitri\Documents\Upwork\Footyamigo\main.py", line 37, in <module>
router.FindCorrectRoute(odd, next_match, local_data, visitor_data)
File "C:\Users\dimitri\Documents\Upwork\Footyamigo\calculator.py", line 3, in <module>
import main
File "C:\Users\dimitri\Documents\Upwork\Footyamigo\router.py", line 1, in <module>
import calculator
File "C:\Users\dimitri\Documents\Upwork\Footyamigo\main.py", line 5, in <module>
import router
What I really need is that mytable is accesible from all files and if I change it's value from any file I have to see the changes reflected on the others, I don't want to have different instances of the object.
Just solved it import __main__ as main inside calculator.py

Wierd attribute error with importing into directories

I have a directory tree as follows:
main.py
dir1
sub1.py
sub2.py
In main.py:
import dir1.sub1
In dir1/sub1.py:
def f1() -> None:
print("f1")
import dir1.sub2
dir1.sub2.f2()
In dir1/sub2.py:
import dir1.sub1
def f2() -> None:
dir1.sub1.f1()
print("f2")
When I run main.py, I get the following error message:
Traceback (most recent call last):
File "...\main.py", line 1, in <module>
import dir1.sub1
File "...\dir1\sub1.py", line 7, in <module>
dir1.sub2.f2()
File "...\dir1\sub2.py", line 5, in f2
dir1.sub1.f1()
AttributeError: module 'dir1' has no attribute 'sub1'. Did you mean: 'sub2'?
(Where the ... at the beginning of the file path is my working directory.)
If I change main.py to
import dir1.sub2
I get a slightly different error message:
Traceback (most recent call last):
File "...\main.py", line 1, in <module>
import dir1.sub2
File "...\dir1\sub2.py", line 1, in <module>
import dir1.sub1
File "...\dir1\sub1.py", line 7, in <module>
dir1.sub2.f2()
AttributeError: module 'dir1' has no attribute 'sub2'
If I move sub1.py and sub2.py to the same directory as main.py and re‐direct imports as necessary, I get the expected output of
f1
f2
Why does this happen, and how can I make it not happen?
You need to use absolute import because Python 3 only supports that. In Python 2 your method will work. So for example if you have import dir1.sub2 change it to from dir1 import sub2. See here.
Note: I've tested it with your setup and it works.

It is a simple source code, but it does not run

import tailer
test = tailer.tail(open("test.txt"), 1)
#print(lines[1])
It's as simple as the code above, but it doesn't work.
(I saved it because it was successful once during the experiment, but an error occurs when I run it again later.)
Error content:
Traceback (most recent call last):
File "c:\Users\user\Documents\VSCODE\python\V1\tailer.py", line 1, in <module>
import tailer
File "c:\Users\user\Documents\VSCODE\python\V1\tailer.py", line 3, in <module>
test = tailer.tail(open("test.txt"), 1)
AttributeError: partially initialized module 'tailer' has no attribute 'tail' (most likely due to a circular import)
Looks like your file is called tailer.py, so when it does import tailer, it tries to load itself, which is usually a recipe for confusion.
You named your program tailer.py. When you do an import tailer the local folder has priority over all other folders and you will import tailer.py again. Creating an import circle.
In other words: you have a name clash between your program and the library you are trying to import. Just rename the file to something else and try again.

importing other file and using functions from main

Note: I have reduced my problem so the code is only a few lines (compared to 600)
I have a problem: from main.py I want to import file slave.py. slave.py references a function from main.py, and of course I get a NameError: name 'funcFromMain' is not defined
Here is my code for main.py:
import slave
def funcFromMain():
return 6
print(slave.funcFromSlave())
And here is my code for slave.py:
def funcFromSlave():
one = funcFromMain() # <- this doesn't work
two = 2
return (one + two)
I am getting exact error: (note that both files are in exactly the same directory)
Traceback (most recent call last):
File "C:\Users\PrinceOfCreation\Documents\test\main.py", line 6, in <module>
print(slave.funcFromSlave())
File "C:\Users\PrinceOfCreation\Documents\test\slave.py", line 2, in funcFromSlave
one = funcFromMain()
NameError: name 'funcFromMain' is not defined
I tried adding import main at the top of slave.py, and got the following error:
Traceback (most recent call last):
File "C:\Users\PrinceOfCreation\Documents\test\main.py", line 1, in <module>
import slave
File "C:\Users\PrinceOfCreation\Documents\test\slave.py", line 1, in <module>
import main
File "C:\Users\PrinceOfCreation\Documents\test\main.py", line 6, in <module>
print(slave.funcFromSlave())
AttributeError: module 'slave' has no attribute 'funcFromSlave'
With from slave import funcFromSlave instead at the top of main:
Traceback (most recent call last):
File "C:\Users\PrinceOfCreation\Documents\test\main.py", line 6, in <module>
print(funcFromSlave())
File "C:\Users\PrinceOfCreation\Documents\test\slave.py", line 2, in funcFromSlave
one = funcFromMain()
NameError: name 'funcFromMain' is not defined
First you can't import a python module like this :
import slave.py
It must be
from slave import funcFromSlave # to get the funcFromSlave function from slave script
And you need to make sure that the slave.py is in the same directory of main.py or
you need to precise the subdirectory where slave.py exists
And for the later error, its best if you avoid circular imports, cause it will create problems, best to do is to send the value of funcFromMain() to funcFromSlave
main.py :
from slave import funcFromSlave
def funcFromMain():
return 6
print(funcFromSlave(funcFromMain()))
slave.py :
def funcFromSlave(funcFromMain):
one = funcFromMain
two = 2
return (one + two)
output when running main.py :
8

python reload module for beginner. importlib.reload doesn't seem to work

I have a file called skdb and class called skmysqldb. I am trying to force reload.
I tried reloading "skdb", "skdb.skmysqldb" "skmysqldb" and none of them seem to work.
>>> from skdb import skmysqldb
>>> importlib.reload(skdb.skmysqldb)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'skdb' is not defined
>>> importlib.reload(skmysqldb)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python36_64\lib\importlib\__init__.py", line 139, in reload
raise TypeError("reload() argument must be a module")
TypeError: reload() argument must be a module
>>> importlib.reload(skdb)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'skdb' is not defined
When you import some object using the from <module> import <obj> syntax as in
from skdb import skmysqldb
the module itself is not added to the current namespace, hence why you get a NameError when you try to do reload(skdb).
Instead try:
import skdb
importlib.reload(skdb)
Be cautious when using reload. If the module your reload imports other modules, those modules are not reloaded recursively, so depending on the exact code you can wind up in a rather broken state where it's better to just restart the whole interpreter.
I don't think this is supported, but try doing del sys.modules['mymodule'] for everything that vaguely matches. To find relevant ones, try something like [x for x in sys.modules if 'mymodule' in x].

Categories

Resources