I have an import error I don't understand. I made a minimal example below, a small namespace package called p_parent which contains no __init__.py file but contains another sub-package called c_child
here is the full arborescence:
p_parent
├── c_child
│ ├── c_main.py
│ └── __init__.py
└── p_main.py
c_main.py and p_main.py contains almost nothing. p_parent/c_child/__init__.py contains only an import.
Here is the shell script which rebuilds this:
mkdir p_parent
mkdir p_parent/c_child
echo '#!/usr/bin/env python3\n\nc_value = 4\n' > p_parent/c_child/c_main.py
echo '#!/usr/bin/env python3\n\np_value = 4\n' > p_parent/p_main.py
echo '#!/usr/bin/env python3\n\nimport p_parent.c_child.c_main as c\n' > p_parent/c_child/__init__.py
When the content of the __init__.py file is import p_parent.c_child.c_main as c I get an error I don't understand when I try to import the submodule:
>>> import p_parent.c_child
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/C/autools/release/2019.09/scade/package/p_parent/c_child/__init__.py", line 3, in <module>
import p_parent.c_child.c_main as c
AttributeError: module 'p_parent' has no attribute 'c_child'
But, what tells me I missed something really important, is that when the content of the __init__.py file is only import p_parent.c_child.c_main everything works as expected (except I have loooong names)
>>> import p_parent.c_child
>>> p_parent.c_child.c_main
<module 'p_parent.c_child.c_main' from '/<snip>/p_parent/c_child/c_main.py'>
>>> p_parent.c_child.c_main.c_value
4
with from p_parent.c_child.c_main * it work somehow, but I would prefere to avoid it:
>>> import p_parent.c_child
>>> p_parent.c_child.c_value
4
What is the logic here ? Why the error is so unintuitive ?
python3.6 is used
Related
I'm trying to build a package where specific modules call other modules. Example of the structure of the package:
provapackage/
├── main.py
└── pippo
├── derivative_functions.py
├── functions_pippo.py
└── __init__.py
content of the functions_pippo module:
def add(x,y):
return x+y
content of the derivative_functions module:
from functions_pippo import add
def add_lst(l):
n=0
for i in l:
n = add(n,i)
return n
content of the main.py file:
from pippo.derivative_functions import add_lst
lst = [1,2,3,4]
print(add_lst(lst))
when I run main.py I get this error:
Traceback (most recent call last):
File "/home/g/Documents/provapackage/main.py", line 1, in <module>
from pippo.derivative_functions import add_list
File "/home/g/Documents/provapackage/pippo/derivative_functions.py", line 1, in <module>
from functions_pippo import add
ModuleNotFoundError: No module named 'functions_pippo'
It seems like python cannot find the functions_pippo module even if it's in the same folder. But when I run derivative_functions.py I don't gat any error message. Is it an import problem?
See this answer here
from .functions_pippo import add
not
from functions_pippo import add
This is a tiny example of my question:
$ tree
.
├── mod
│ ├── a.py
│ ├── b.py
│ └── __init__.py
└── test.py
The code of test.py:
from mod import testB
if __name__ == '__main__':
testA()
testB()
The code of a.py:
def testA():
print("TEST A")
The code of b.py:
from a import testA
def testB():
print("TEST B CALLS TEST A")
testA()
The code of __init__.py:
from .a import *
from .b import *
And test.py fails when I call as it:
$ python3 test.py
Traceback (most recent call last):
File "test.py", line 1, in <module>
from mod import testB
File "/tmp/mod/__init__.py", line 2, in <module>
from .b import *
File "/tmp/mod/b.py", line 1, in <module>
from a import testA
ModuleNotFoundError: No module named 'a'
How do I change the __init__.py or b.py?
I learning python module , I want to put some file to one mudole dir, and then call it at the project root. but it not work. I try to solve it , but it still not success!
what is the problem ?
├── calculator
│ ├── __init__.py
│ ├── addTwo.py
│ ├── mulTwo.py
│ └── sum.py
└── main.py
# calculator/__init__.py
#nothing
# calculator/addTwo.py
def addFunc(lhs, rhs):
return lhs + rhs
# calculator/mulTwo.py
def mulFunc(lhs, rhs):
return lhs * rhs
# calculator/sum.py
import addTwo
def sumFunc(arg1, arg2, arg3):
ans = addTwo.addFunc(arg1,arg2)
ans = addTwo.addFunc(ans,arg3)
return ans
#main.py
from calculator import addTwo
from calculator import mulTwo
from calculator import sum
def test():
print(addTwo.addFunc(1,2))
print(mulTwo.mulFunc(1,2))
print(sum.sumFunc(1,2,3))
if __name__ == '__main__':
test()
run it
cong.lin#C02YN3P4LVCK ~/Program/python/module_test python3 main.py
Traceback (most recent call last):
File "main.py", line 4, in <module>
from calculator import sum
File "/Users/cong.lin/Program/python/module_test/calculator/sum.py", line 1, in <module>
import addTwo
ModuleNotFoundError: No module named 'addTwo'
✘ cong.lin#C02YN3P4LVCK ~/Program/python/module_test
You have to provide PYTHONPATH to root of your project
Try
export PYTHONPATH=$PWD
before running
python3 main.py
While trying to learn how Python modules and packages work, I have the following error that I can't find a way around:
$ ./myMain.py
Traceback (most recent call last):
File "./myMain.py", line 6, in <module>
print(foobar.getKey['A'])
TypeError: 'function' object is not subscriptable
My directory structure is the following:
.
├── myMain.py*
└── utils/
└── Foo/
├── __init__.py
├── __pycache__/
│ ├── __init__.cpython-36.pyc
│ └── foobar.cpython-36.pyc
└── foobar.py
and myMain.py would be the main script from where the package would be imported. myMain.py has the following code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from utils.Foo import foobar
print(foobar.getKey['A'])
__init__.py is an empty file, and foobar.py has the function definition:
TEST_DICT = {
'A': 'This is A',
'B': 'This is B'
}
def getKey(letter):
return TEST_DICT[letter]
What am I doing wrong here?
After trying to run the code in myMain.py from within the Python interpret, I realised that the function call was writen with wrong syntax. Instead of foobar.getKey['A'] one should have instead foobar.getKey('A') because we are calling the function and not the dictionary object.
I have a project structure as the following
src/
scripts/
script1
mylib
__init__.py
a_module.py
These are the contents of __init__.py
__version__ = '0.0.1'
But if I try to do this on script1:
from mylib import __version__ as _ver
It fails with this:
Traceback (most recent call last):
File "./script1", line 2, in <module>
from mylib import __version__ as _ver
ImportError: cannot import name '__version__'
Changing the var name doesn't help at all, i.e. this fails, too:
from mylib import a_ver as _ver
Every other variable in any other module gets imported correctly, e.g.
from mylib.a_module import a_var
Why? And how can I work around this?
You can use:
import mylib
_ver = mylib.__version__
del mylib