Importing a file that imports another file - python

I would like to import a file that also imports another file.
I currently have the following directory structure:
.
├── main.py
└── foo
├── file1.py
├── file2.py
└── file3.py
With the following code:
# main.py
from foo.file1 import func1
func1()
# foo/file1.py
from file2 import func2
from file3 import func3
def func1():
# Do stuff
func2()
func3()
if __name__ == "__main__":
# Do some other stuff
func1()
# foo/file2.py
from file3 import func3
def func2():
# Do stuff
func3()
# foo/file3.py
def func3():
# Do stuff
If I run main.py, I get ModuleNotFoundError: No module named 'file2'.
I could replace the line from file2 import func2 in foo/file1.py with from foo.file2 import func2 and do the same for the file3 import but then I could not run foo/file1.py on its own.
What would be the recommended way to fix this?

Python3 doesn't support Implicit Relative Imports e.g. from file2 import func2, we need to use Explicit Relative Imports e.g. from .file2 import func2.
In foo/file1.py change:
from file2 import func2
from file3 import func3
To:
from .file2 import func2
from .file3 import func3
And in foo/file2.py change:
from file3 import func3
To:
from .file3 import func3
You might want to read: Absolute vs Relative Imports in Python

Related

Initialize module only once on imports from multiple files

I have multiple python scripts, like this:
utils.py
module1.py
module2.py
module3.py
main.py
...
In utils.py:
import some_lib
role_id = "some_key_1"
secret_id = "some_key_2"
def initialize():
real_key = some_web_request(role_id, secret_id)
some_lib.init(real_key)
# define some other functions using some_lib
In module1.py, module2.py, module3.py:
import utils
# define some other functions using functions in utils.py
In main.py:
import module1
import module2
import module3
# do something
I want to run utils.initialize() only once for initializing some_lib. However, due to how import works in python, if I put initialize() on global area in utils.py then it will run on every import statement run.
I can implement this like this, in utils.py
import some_lib
initialized = False
def initialize():
# same as above
if not initialized:
initialize()
initialized = True
Is this a good practice? Is there better or elegant way to implement this?

How to import a file from a sibling directory in Python..?

How to import a file from a sibling directory in Python..?
Eg.
Root> DirA>File1.py
Root>DirB>File2.py
I want to import File1.py into File2.py.
File2.py
from File2.py import abc
Thanks in advance..
I think you can import File1.py intoFile2.py like below.
# File1.py
def func1():
print("Function from File1.py")
# File2.py
import sys
sys.path.append("../DirA")
from File1 import func1
func1()
# >>> Function from File1.py

Import in a module fails because __name__ is __main__

Here is my project structure:
Project
main.py
myPackage/
subfolder1/
__init__.py
script11.py
script12.py
subfolder2/
__init__.py
script2.py
__init__.py
in main.pyI import script2.py the following way :
from myPackage.subfolder2 import script2 as script2
then, I call a function from script2.py in main.py with :
bar = script2.foo()
and in script2 I need to import a function from script1 :
from ..subfolder1.script11 import my_function
and it breaks with the error :
attempted relative import with no known parent package
I have inspected the __name__ variable and indeed it has the value __main__. How can I manage that properly ?
All you should have to do is change your import in main.py to from myPackage.subfolder2 import script2. I set up a directory and some files in this way, using that import, and the script runs as expected:
main.py
myPackage/
subfolder1/
script11.py
subfolder2/
script2.py
script11.py
def bar():
return 10
script2.py
from ..subfolder1.script11 import bar
def foo():
x = bar()
print('foo is', x)
main.py
from myPackage.subfolder2 import script2 as s2
s2.foo()
Running:
>>> py .\main.py
foo is 10
Some notes:
I'm assuming Python 3, since Python 2 was deprecated beginning of this year
In Python 3, the __init__.py files aren't necessary to make a package, but having them doesn't hurt anything. You can leave them out if you want.
The as script2 part in from subfolder2 import script2 as script2 is redundant. It will already be imported as script2.

Import error raised when importing file1.py in file2.py where file2.py also imports file1.py [duplicate]

This question already has answers here:
Circular dependency in Python
(5 answers)
Closed 3 years ago.
I my Python Pyramid files, File2.py is importing File1.py and File1.py is importing File2.py, which is creating an infinite loop and raising Import error. I need to import these to use the public varibles of the classes as well as therir functions. How do i achieve this ?
I tried below :
File2.py
Class File2 :
def __init__(self, sessionId):
from server.eventmanager.file1 import File1 # : Doesnt Work
if __name__ == "__main__":
from server.eventmanager.file2 import File2 # : Doesnt Work(Tried both(init+ main)/either
def myFunc(self):
print(File1.myvar)
File1.py
from /server/modules/mymodule/file2 import File2
Class File1:
def __init__(self):
pass
myvar = False
def updateMyVar(self,updatedvar):
cls.myvar=updatedvar
#Do Something
File "/server/eventmanager/file1.py", line 7, in <module>
from server.modules.mymodule.File2 import file2
File "/server/modules/mymodule/file2.py", line 13, in <module>
from server.eventmanager.File1 import file1
ImportError: cannot import name 'file1'
I think you are looking for cyclic dependency in python
Circular dependency in Pythonenter link description here
you can have look how to resolve them.
You can add above your first import an if clause.
If I understood you right then you start your code with File2.py.
In this case you should do it like that:
if __name__ == "__main__":
import file1
If you run File2.py __name__ will be __main__. As a result the if - clause is true and you import File1.py. Well now File1.py imports File2.py but this time __name__ isn't __main__ because it doesn't run as a "main-file". This time __name__ will be File1 and File1 doesn't import Test2 anymore because the if clause stops it, but it still has the code of it because it already imported it one time.
Edit:
Ok I got it! You have to put the if __name__ == "__main__" clause at the top of your code in your File1.py:
if __name__ == "__main__":
from server.eventmanager.file2 import file2 # Doesnt Work(Tried both(init+ main)/either
from server.eventmanager.file1 import File1 # : Doesnt Work
class File2:
def __init__(self, sessionId):
pass
def myFunc(self):
print(File1.myvar)

Override function in a module with complex file tree

I have a module module containing 2 functions a and b splited into 2 different files m1.py and m2.py.
The module's file tree:
module/
__init__.py
m1.py
m2.py
__init__.py contains:
from .m1 import a
from .m2 import b
m1.py contains:
def a():
print('a')
m2.py contains:
from . import a
def b():
a()
Now, I want to override the function a in a main.py file, such that the function b uses the new function a. I tried the following:
import module
module.a = lambda: print('c')
module.b()
But it doesn't work, module.b() still print a.
I found a solution, that consists in not importing with from . import a but with import module.
m2.py becomes:
import module
def b():
module.a()

Categories

Resources