Python Name Error during importing function from sibling directiry - python

My project in java and I am using some python scripts for other tasks. My python scripts directory structuring are as follows:
Parent Dir
- Scripts (driver.py)
- utils (common.py, helper.py)
I want to use functions & classes from common.py & helper.py in driver.py classes. I am importing these in driver.py like this:
sys.path.append("..")
from utils import *
configs = load_config(filepath)
but when I use some functions from common.py (lets assume common.py imports class TestClass from helper.py and also has function load_config(filepath)) it throws error-
NameError: name 'load_config' is not defined

You cannot import an entire directory like that. You need to import the files individually. You can add a __init__.py file to your utils folder that will be executed when you import the directory the way you are doing. Then you can choose whatever behavior you would like to be carried out in the __init__.py
For instance, your __init__.py could look like this:
__all__ = ["common", "helper"]
This means that when you call from utils import *, the * will import the modules listed in __all__
Keep in mind you will still need to call common.function_name() if you want to use a function from within common.

Related

How to import from submodules without including "submodules_dir" in the import statement

I have a Python project with several Git submodules structured like so:
myproject/
__init__.py
src/
__init__.py
main.py
submodules/
__init__.py
submodule1/
__init__.py
utils.py
submodule2/
...
I want to be able to import code in main.py from my submodules with the following constraints:
The import statement must not contain submodules
IntelliSense must function. This rules out modifying the PATH, e.g. via sys.path.append().
The submodules must not be installed using a package manager.
I am hoping for an import statement in main.py that looks something like from submodule1 import utils or from submodule1.utils import myUtilFunction.
If this is impossible, any explanation or resources to help me understand why would be appreciated. I have been reading the docs about the import function, modules, and namespaces, but I do not understand how to achieve this or if it's even possible.
I've tried using various combinations of import statements and __all__ declarations in my __init__.py and files like so:
myproject/__init__.py:
__all__ = ['submodule1', 'submodules/submodule1']
from .submodules.submodule1 import *
from .submodules import *
import .submodules.submodule1
myproject/submodules:
__all__ = ['submodule1']
from .submodule1 import *
myproject/src/main.py:
from submodule1.utils import myUtilFunction
But so far nothing has allowed from submodule1.utils import myUtilFunction to work in main.py.

creating module in python - how imports work

I'm creating a module in a python app, I have my primary code file, and I want to import some helper methods/classes from a helper folder. This is what I have for my folder structure:
module:
__init__.py
helpers:
__init__.py
some_class.py
this is module/helpers/__init__.py file:
from .some_class import SomeClass
def helper_method_1():
# code
def helper_method_2():
# code
so my question is: is importing SomeClass inside module/helpers/__init__.py inside the helpers enough to use it as in import in my main module/__init.py file?
this is what I'm trying in my module/__init__.py
from .helpers import (SomeClass, helper_method_1, helper_method_2)
I'm kind of in the middle of doing a bunch of things, so can't test it for errors at the moment
Yes, it is enough.
Unless module has __all__ variable, all names (including names imported from other modules) are exported.

Import local packages in python

i've run through many posts about this, but still doesn't seem to work. The deal is pretty cut. I've the got the following hierarchy.
main.py
DirA/
__init__.py
hello.py
DirB/
__init__.py
foo.py
bla.py
lol.py
The__init__.py at DirA is empty. The respective one at DirB just contains the foo module.
__all__.py = ["foo"]
The main.py has the following code
import DirA
import DirB
hey() #Def written at hello.py
foolish1() #Def written at foo.py
foolish2() #Def written at foo.py
Long story short, I got NameError: name 'foo' is not defined. Any ideas? Thanks in advance.
You only get what you import. Therefore, in you main, you only get DirA and DirB. You would use them in one of those ways:
import DirA
DirA.something_in_init_py()
# Importing hello:
import DirA.hello
DirA.hello.something_in_hello_py()
# Using a named import:
from DirA.hello import something_in_hello_py
something_in_hello_py()
And in DirB, just make the __init__.py empty as well. The only use of __all__ is for when you want to import *, which you don't want because, as they say, explicit is better than implicit.
But in case you are curious, it would work this way:
from DirB import *
something_in_dirb()
By default the import * will import everything it can find that does not start with an underscore. Specifying a __all__ restricts what it imported to the names defined in __all__. See this question for more details.
Edit: about init.
The __init__.py is not really connected to the importing stuff. It is just a special file with the following properties:
Its existence means the directory is a python package, with several modules in it. If it does not exist, python will refuse to import anything from the directory.
It will always be loaded before loading anything else in the directory.
Its content will be available as the package itself.
Just try it put this in DirA/__init__.py:
foo = 42
Now, in your main:
from DirA import foo
print(foo) # 42
It can be useful, because you can import some of your submodules in the __init__.py to hide the inner structure of your package. Suppose you build an application with classes Author, Book and Review. To make it easier to read, you give each class its own file in a package. Now in your main, you have to import the full path:
from myapp.author import Author
from myapp.book import Book
from myapp.review import Review
Clearly not optimal. Now suppose you put those exact lines above in your __init__.py, you may simplify you main like this:
from myapp import Author, Book, Review
Python will load the __init__.py, which will in turn load all submodules and import the classes, making them available on the package. Now your main does not need to know where the classes are actually implemented.
Have you tried something like this:
One way
from DirA import hello
Another way
from DirA.hello import hey
If those don't work then append a new system path
You need to import the function itself:
How to call a function from another file in Python?
In your case:
from DirA import foolish1, foolish2

Executing python class code located in folders

I currently have a folder structure like this:
.
├── main.py
└── parent.py
└── classes
└── subclass1.py
└── subclass2.py
└── subclass3.py
Each of the subclasses are a subclass of parent, and parent is an abstract class. The subclasses need to execute some functions like mix() and meld(), and each of these subclasses must implement mix() and meld().
I would like to write main.py such that the functions in each of the subclasses are executed, without me having to import their files into my program. That is, I'd like something akin to the following to happen:
def main():
# Note that I don't care about the order of which these
for each subclass in the sources folder:
execute `mix()` and `meld()`
# Note that I don't mind which order the order
# of which the subclasses' functions are invoked.
Is there any way I could get this to happen?
Essentially, what I want to do is drop a bunch of classes into the classes folder, with only mix() and meld() defined, and let this program run wild.
I've never tried this, but I think it does what you're asking for:
import os
import imp
import runpy
package = 'classes'
_, path, _ = imp.find_module(package)
for m in os.listdir(path):
if m.endswith('.py'):
runpy.run_module(
package + '.' + os.path.splitext(m)[0],
run_name="Mix_Meld"
)
Then, inside of your subclasses, you can write:
if __name__ == 'Mix_Meld':
ClassName.mix()
ClassName.meld()
This may result in additional code, granted, but if you ever need to stop the execution in one of the files, doing so is just a matter of commenting out that part of the code.
Another advantage is extensibility and polymorphism; if you need to run the code a bit differently for each one of these modules in the future, you only have to change the behaviour in the specific modules. The callee (main.py) will remain oblivious to those changes and continue calling the modules the usual way.
Try importing from the subfolder in the main.py program file:
from glob import *
import os
for i in glob.glob(os.path.join('classes', '*.py')):
__import__(i); className = i[:-3].capitalize()
eval(className).mix(); eval(className).meld()

Python import module from relative folder

i'm creating a python program, and i want to split it up into seperate files. I'm using import to do this, but its not working (specifically, a variable is stored in one python file, and its not being read by the main one.
program /
main.py
lib /
__init__.py
config.py
functions.py
I have in main.py:
import lib.config
import lib.functions
print(main)
and config.py has
main = "hello"
I should be getting the output "hello", when i'm executing the file main.py, but i'm not. I have the same problem with functions stored in functions.py
Any help would be great,
Importing the module with a simple import statement does not copy the names from that module into your own global namespace.
Either refer to the main name through attribute access:
print(lib.config.main)
or use the from ... import ... syntax:
from lib.config import main
instead.
You can learn more about how importing works in the Modules section of the Python tutorial.

Categories