How do I import all functions from a package in python? - python

I have a directory as such:
python_scripts/
test.py
simupy/
__init__.py
info.py
blk.py
'blk.py' and 'info.py are modules that contains several functions, one of which is the function 'blk_func(para)'.
Within '__init__.py' I have included the following code:
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
file_lst = os.listdir(dir_path)
filename_lst = list(filter(lambda x: x[-3:]=='.py', file_lst))
filename_lst = list(map(lambda x: x[:-3], filename_lst))
filename_lst.remove('__init__')
__all__ = filename_lst.copy()
I would like to access the function 'blk_func(para)', as well as all other functions inside the package, within 'test.py'. Thus I import the package by putting the following line of code in 'test.py':
from simupy import*
However, inorder to use the function, I still have to do the following:
value = blk.blk_func(val_param)
How do I import the package simupy, such that I can directly access the function in 'test.py' by just calling the function name? i.e.
value = blk_func(val_para)

Pretty easy
__init__.py:
from simupy.blk import *
from simupy.info import *
Btw, just my two cents but it looks like you want to import your package's functions in __init__.py but perform actions in __main__.py.
Like
__init__.py:
from simupy.blk import *
from simupy.info import *
__main__.py:
from simupy import *
# your code
dir_path = ....
It's the most pythonic way to do. After that you will be able to:
Run your script as a proper Python module: python -m simupy
Use your module as library: import simupy; print(simupy.bar())
Import only a specific package / function: from simupy.info import bar.
For me it's part of the beauty of Python..

Related

Importing Functions From Another Directory Using A Function?

I'm using Python 3.9
I have the following structure:
parent_folder
|
|-->. useful_functions.py .
|-->. script_folder_1 .
|
|-->. script_1.py
|-->. function_import.py
|-->. script_folder_2 .
|
|-->. script_2.py
|-->. function_import.py
script_1.py and script_2.py are very similar (but not identical), and so both want to use the functions stored in useful_functions.py
I have worked out that I can import the functions from useful_functions.py by putting the following at the top of script_1.py and script_2.py:
import sys
import os
local_dir = os.getcwd()
dir_up = os.path.dirname(local_dir)
sys.path.append(dir_up)
import useful_functions as uf
This works, meaning it allows script_1.py to call functions from useful_function.py as uf.function_name(arguments)
Since this text block is identical in script_1.py and script_2.py, I wanted to pull it out and make it a function in a different file function_import.py, since that way if I need to modify it I can modify the standalone file in script_folder_1 and copy it to script_folder_2.
However, when I create function_import.py, function_import.py is able to "locally" access the functions from useful_functions.py, but script_1.py is not able to access the functions from useful_functions.py.
Details:
def function_import():
import sys
import os
import re
local_dir = os.getcwd()
dir_up = os.path.dirname(local_dir)
sys.path.append(dir_up)
import useful_functions as uf
print(uf.test_function())
script_1.py:
import function_import
function_import.function_import()
uf.test_function()
When I run script_1.py in the terminal, uf.test_function() returns 3, the placeholder value, inside of function_import(), but then when script_1.py calls uf.test_function(), I get:
NameError: name 'uf' is not defined
Is there a way to allow a function inside a script to import modules for the script to use? Or is there some other way entirely that I should be doing this?
I read these posts and they didn't seem to have a good solution to my problem:
https://stackoverflow.com/search?q=import+from+parent+directory+python&s=5452f193-c78d-4966-b69a-896fb6a5a5f8
Import Script from a Parent Directory
This doesn't define a function inside function_import.py but it does the job
function_import.py:
import sys
import os
import re
local_dir = os.getcwd()
dir_up = os.path.dirname(local_dir)
sys.path.append(dir_up)
import useful_functions as uf
useful_functions.py:
def test_function():
print('In the test function')
script_1.py:
from function_import import uf
uf.test_function()
Outputs In the test function
It's not the perfect solution but you can wrap your function into another one like so :
function_import.py:
def function_import():
import sys
import os
import re
local_dir = os.getcwd()
dir_up = os.path.dirname(local_dir)
sys.path.append(dir_up)
import useful_functions as uf
#print(uf.test_function())
def uf_test_function(*args, **kwargs):
uf.test_function(*args, **kwargs)
script_1.py:
import function_import
function_import.function_import()
function_import.uf_test_function()

ModuleNotFoundError: I can't import custom modules properly

below the folder structure of my software:
below the code of all the .py files:
run.py:
import modules.module_01.aa as a
a.test()
# test:
if __name__=="__main__":
pass
aa.py (module 1):
import libraries.qq as q
import libraries.zz as z
def test():
q.qq_fun()
z.zz_fun()
print("ciao")
qq.py (library used by aa.py):
def qq_fun():
pass
zz.py (library used by aa.py):
def zz_fun():
pass
my question is really simple, why when I run "run.py" Python say to me:
why "aa.py" can't import the module "qq.py" and "zz.py"? how can I fix this issue?
run.py
In run.py, the Python interpreter thinks you're trying to import module_01.aa from a module named module. To import aa.py, you'll need to add this code to the top of your file, which adds the directory aa.py is in to the system path, and change your import statement to import aa as a.
import sys
sys.path.insert(0, "./modules/module_01/")
aa.py
The same problem occurs in aa.py. To fix the problem in this file, you'll need to add this code to the top of aa.py, which adds the directory qq.py and zz.py are in, and remove the libraries. from both of your import statements.
import sys
sys.path.insert(0, "./modules/module_01/libraries")

relative import of modules in pytest in a Scafold structure

using pyscafold in order to build a module I get an structure as follows
scr
---module
------__init__.py
------file.py (containing func inside)
tests
---fileTest.py
How is the right way to import file.py in the test file fileTest.py?
So far many of this variations dont work:
import pytest
from ../src/module import func
including this in init.py does not help:
import os, sys
sys.path.append(os.path.dirname(os.path.realpath(__file__)))
These do not help:
from .src/module/myfile import func
from ..src/module/myfile import func
There should not be forward slashes in your imports.
Also:
add a __init__.py file in tests directory
in fileTest.py, you should have:
import pytest
from src.module.file import func
Then, make sure the current working directory is the parent directory of src and run pytest .

Import all files in current directory

I have just started a python project. The directory structure is as follows:
/algorithms
----/__init__.py
----/linkedlist
--------/__init__.py
--------/file1.py
--------/file2.py
/tests
----/test_linkedlist
You can also check the Github repository.
In each of the sub folders under algorithms, in the __init__ file I am including the following for all the files one by one:
from .file1 import *
from .file2 import *
And so on.
The task that I am trying to achieve is running all tests together using the query:
python3 -m unittest discover tests
Each file in the tests directory starts as follows:
from algorithms.linkedlist import *
import unittest
Right now if I want to add a new file to the linkedlist directory, I create the file and then add another from .filename import * in the __init__ file.
How do I write a script in the __init__ file so that each time I create a new file, I do not have to manually insert the import command?
So the __init__ is in the same folder? As the docs say The import statement is syntactic sugar for the __import__ function.
So we can use:
import importlib
import glob
for file in glob.iglob('*.py'):
importlib.__import__(file)
Some reasons why this does not work:
You want to load the functions in the module - the import * from syntax. With this code you can only run file1.test.
You run the script loading from another directory, which confuses glob. We have to specify the actual working directory.
__import__ prefers to know the module name.
To find the solution I combine the import * from function from this answer with pkgutil.walk_packages from this blog.
import importlib
import pkgutil
def custom_import_all(module_name):
""" Use to dynamically execute from module_name import * """
# get a handle on the module
mdl = importlib.import_module(module_name)
# is there an __all__? if so respect it
if "__all__" in mdl.__dict__:
names = mdl.__dict__["__all__"]
else:
# otherwise we import all names that don't begin with _
names = [x for x in mdl.__dict__ if not x.startswith("_")]
# now drag them in
globals().update({k: getattr(mdl, k) for k in names})
__path__ = pkgutil.extend_path(__path__, __name__)
for importer, modname, ispkg in pkgutil.walk_packages(path=__path__, prefix=__name__+'.'):
custom_import_all(modname)

Python import class from other files

I have three files under the same directory, namely, main.py, Newtester.py, and fileUtility.py. In Newtester.py there is a class named Function. In main.py, there are the following codes:
from file.py import *
...
def main():
...
funcs = parseFuncSpec(funcInputFile)
parseFuncSpec is defined in fileUtilities.py as:
some code to import Newtester.py
def parseFuncSpec(fName):
curFunc = function(funcName, numTest, [], score)
Regardless of what I put in import Newtester.py, I always get an error saying "Function" (the class defined in the file "Newtester.py") is not defined. Following Python: How to import other Python files, I have attempted
import Newtester
__import__("Newtester")
exec("Newtester.py")
exec("Newtester")
import importlib
importlib.__import__("Newtester")
os.system("Newtester.py")
But none of them seemed to work. Any advice is appreciated. See https://github.com/r2dong/unitTesting if you are interested in seeing the complete files.
It's because you are not using it correctly
well when you use import statement like below only Newstester file is imported
import Newtester
hence instead of using parseFuncSpec() directly you have to use it as Newtester.parseFuncSpec()
or to use parseFuncSpec() directly you need to use below import statement:
from Newtester import parseFuncSpec

Categories

Resources