Want to learn the proper way for importing modules with folder
/garden
__init__.py
utilities.py
someTools.py
/plants
__init__.py
carrot.py
corn.py
Inside /plants/__init__.py I have
__all__ = ['carrot', 'corn']
from . import *
inside carrot.py
def info():
print "I'm in carrot.py"
When I do
import garden
garden.carrot.info()
# got correct result
I'm in carrot.py
My question is how do I correct namespace for utilities.py for example inside carrot.py and corn.py. I want to use function in utilities.py
Inside carrot.py when I
import utilities as util
# try use it and got global name error
util.someFunc()
# NameError: global name 'util' is not defined #
Can I configure __init__.py in plants folder so that it import all the modules inside garden? Like utilities and sometools ? so I don't have to import utilities in both carrot.py and corn.py and be able to use utilities ?
note: all __init__.py files are empty.
main.py
app/ ->
__init__.py
package_a/ ->
__init__.py
fun_a.py
package_b/ ->
__init__.py
fun_b.py
app/package_a/fun_a.py
def print_a():
print 'This is a function in dir package_a'
app/package_b/fun_b.py
from app.package_a.fun_a import print_a
def print_b():
print 'This is a function in dir package_b'
print 'going to call a function in dir package_a'
print '-'*30
print_a()
main.py
from app.package_b import fun_b
fun_b.print_b()
if you run $ python main.py it returns:
This is a function in dir package_b
going to call a function in dir package_a
------------------------------
This is a function in dir package_a
main.py does: from app.package_b import fun_b
fun_b.py does from app.package_a.fun_a import print_a
If you have app in your PYTHONPATH, then from anywhere you can >>> from app.package_...
so file in folder package_b used file in folder package_a, which is what you want. Right??
Related
Simply speaking, I have this directory structure:
src/
my_file1.py
tests/
__init__.py
my_file1_test.py
In my_file1.py:
def my_func1(a):
return a + 99
How do I then access my_func1 from the tests? In my_file1_test.py I can't access the method:
# from ??? import ?? # is this needed at all?
def my_test1():
res = my_func1(123) # unaccessible
assert res = 222
Will I have to create __init__.py in scr directory first?
update1
from src.myfile import my_func1
===>
ModuleNotFoundError: No module named 'scr'
And if I add __init__.py then it'll become:
ImportError: cannot import name 'my_func1' from 'src'
If you run pytest from your project root with
python -m pytest
you then have to import the function, as you guessed, with:
from src.myfile import my_func1
Have a module in a subdirectory and when I try to import it, I get a NameError: namefoois not defined. When I put the class code directly into the __main__.py file it works fine. __init__.py files are empty.
I've tried the following all with other errors:
MyProject/
├── __init__.py
├── __main__.py
├── foo/
│ ├── bar.py
│ ├── __init__.py
bar.py
class Bar:
def __init__(self):
print( 'am here' )
pass
__main__.py
from MyProject import foo
#from MyProject import bar # errors with cannot import bar from MyProject
#from foo import bar # errors with No module named foo
if __name__ == '__main__':
w = Bar()
Is there perhaps a better way to organise this?
The Bar class is in the file bar.py, so I think you'd need to do
from MyProject.foo import bar
w = bar.Bar()
or
from MyProject.foo.bar import Bar
w = Bar()
You didn't share your foo/__init__.py, but you could fix the situation by adding something like this to it:
from .bar import Bar
That adds Bar to the namespace of foo and causes Python to find Bar when you just import foo.
However, you would probably do well to look at a few standard examples for writing a package. For one, you probably shouldn't name your project MyProject, as that name signals it's a class (with TitleCase). Naming it 'project' further confuses the issue, as it appears you're writing a package, so my_package sounds about right.
If you dont know from what direcrory file will be runed then use . to show where package is
from .foo.bar import Bar
or
from .foo import bar
w = bar.Bar()
or
import .foo
w = foo.bar.Bar()
. before package name means that package lockated in same directory with current file
I am running a python project like this:
project
Test.py
COMMON.py
SYSTEM.py
PTEST1
Hello.py
when run the code "Test.py" it will show NameError, I am not sure why?
But if I replaced the "from SYSTEM import *" with "from COMMON import *" in Test.py and PTEST1/Hello.py, it works as expect.
#Test.py is like this:
from SYSTEM import *
myvalue.Hello.printf()
# COMMON.py is like this:
myvalue = lambda: None
from PTEST1.Hello import Hello
myvalue.Hello = Hello
# SYSTEM.py is like this:
from COMMON import *
#PTEST1/Hello.py
from SYSTEM import *
class Hello():
#staticmethod
def printf():
print("Hello1")
print(vars(myvalue))
I expect there is no "NameError" by not changing import code. BTW, my python is 3.6+
Good practice is to give filenames in lowercase.
It looks like you are creating a Python project under project/. Any directory needs to have a file __init__.py in every directory in order for it to be discovered in Python.
You then need to refer to modules by their full name (not relative naming).
So the directory structure should be:
project/
__init__.py
test.py
common.py
system.py
ptest1/
__init__.py
hello.py
Every time you refer to file you should give the full path.
# import everything from hello.py
from project.ptest1.hello import *
# import everything from common.py
from project.common import *
# import everything from system.py
from project.system import *
I have dir structure like this:
Proj/
run.py
Util/
__init__.py
x.py
y.py
In x.py, I define a function:
def p():
return 1
In y.py, I define:
def q():
return 2
Currently in run.py, I'll use
from Util import *
But I have to call them using
x.p()
y.q()
But I want to call them using
p()
q()
Is there a way that I can do that? Like (as I imagine)
from Util.* import *
Bring the names up into the package namespace, by using star imports in the __init__.py:
# in util/__init__.py
from util.x import *
from util.y import *
In each submodule, define the names which you want to export by using the __all__ name:
# in x.py
__all__ = ['p']
And:
# in y.py
__all__ = ['q']
This is a pretty standard usage of the __init__.py module within a package, documented here.
I have my .py module which is in C:\Python_Projects\MyModules\ with the name button_generator.py.
My code goes something like this:
module_path='C:\\Python_Projects\\MyModules'
module_name='button_generator.py'
sys.path.append(module_path)
try:
limp=importlib.import_module(module_name.split('.')[0])
except:
print 'module import error'
I have tried other versions aswell:
importlib.import_module(module_name) without the split
importlib.import_module('C:\Python_Projects\MyModules\button_generator.py')
importlib.import_module('C:\Python_Projects\MyModules\button_generator')
The folder C:\Python_Projects\MyModules is in my sys.path as I checked during debug.
Why wouldn't the module import?
I suggest you to reorder your project directories and avoid calling other modules which are not in your current directory project. You'll avoid those kind of errors.
For example, let's organize our project directories and folders to look something like this:
MyProjectFolder/
├── main.py
└── modules
├── __init__.py
└── MyLib.py
NB: Don't forget to add an empty file called __init__.py
MyLib.py :
#!/usr/bin/python3
class MyLib:
def __init__(self):
self.say_hello = "Hello i'm in modules/MyLib"
def print_say_hello(self):
print(self.say_hello)
main.py:
#!/usr/bin/python3
# from folder.file import class
from modules.MyLib import MyLib
class MainClass:
def __init__(self):
my_lib = MyLib() # load MyLib class
my_lib.print_say_hello() # access to MyLib methods
### Test
if __name__ == '__main__':
app = MainClass()
In terminal when i run:
$ python3 main.py
output:
Hello i'm in modules/MyLib
So here we have successfully imported the class in modules/MyLib.py into our main.py file.
I found the error:
After treating the ImportError exception by printing it's args, I noticed that button_generator.py had an Import that was not resolving. Basically, button_generator.py could not be imported because it had a wrong import.