I have a very simple file setup:
test.py
package/
__init__.py
file_1.py
With the contents of each file being:
# in test.py
import package
# in file_1.py
foo = 5
With the __init__ file being blank. I've been told on multiple occasions that leaving the __init__ file blank is perfectly fine. Then why then, in test.py can I not access foo by saying package.foo? This seems incredibly trivial to me, yet I cannot figure out why it's not working. If I put a print function in file_.py that doesn't seem to get activated either upon running test.py, so what is my problem?
It doesn't work like this. You cannot access package.foo since there is no foo in package.__init__. Since code in __init__ doesn't import file_1 or file_1.foo.
You can do import package.file_1 and then access package.file_1.foo or from package.file_1 import foo and then access foo.
Also there can be no __init__.py at all.
Related
I have the following file structure:
parentfolder/
utils.py
myProgram/
main.py
other.py
I will be running the main.py which utilizes other.py which needs to utilize everything in utils.py (NOT just import one method from utils.py at a time - there are global variables and functions that call other functions within this file.)
I have tried lots of different examples online utilizing sys, path, etc. Along with adding __init__.py in none, some, and all directories. None of which worked for me.
How do I go about this importing of utils.py within other.py?
If I need to create init.py files could you also specify where they need to be created and if anything needs to be placed in them? Do I need to run them once before running the main.py the first time?
Thank you so much for any help in advanced
Yes you should add init files as in:
parentfolder/
__init__.py
utils.py
myProgram/
__init__.py
main.py
other.py
Those can be empty or better containing a docstring on the package contents, but you should not run them or anything
The correct way is to run your script from the parent folder of the parentFolder using the module path:
$ cd parentfolder/..
$ python -m parentFolder.myProgram.main
This way the import utils statement will work without the sys.path hack which can lead to subtle bugs
I'm new to Python and am working through its idiosyncrasies, and am having problems with something that should be simple. I have main directory with main.py and some other files, and I have a subfolder holding classes for some specific processing. So let's say my file structure looks like this:
root/main.py
root/more/foo.py
root/more/bar.py
File foo looks like this:
from bar import bar
class Foo():
def __init__():
myBar = bar()
if __name__ == '__main__':
G = Foo()
print(G.myBar)
Main.py looks like:
import more.foo as f
.
.
.
When this line is called, the interpreter has no problem finding foo, but the import line raises an error in foo.py:
ModuleNotFoundError: No module named 'bar'
When I run foo natively, it has no problem finding bar and functions effectively. Can you help me what's going on here, and what I can do to circumvent this issue?
I'm running Python 3.7 in OSX using PyCharm.
I am assuming that when you say you run foo natively, you are in the folder more.
To solve your issue, you simply need to import all classes everywhere in relation to its position from the root directory, because the entry point is in main.py.
This should work if you import bar from more.bar:
from more.bar import bar
I have a module with multiple files structured like this:
/bettermod/
├── __init__.py
├── api.py
├── bettermod.py
├── errors.py
└── loggers.py
From bettermod.py, I'm trying to import two things:
a class called API from api.py
the whole errors.py file
For the first thing, it is quite easy, I just have to do this:
from .api import API
However, for importing the whole errors.py file, I'm encountering a problem; I'm trying to do like this:
from . import errors
which should work, according to this python documentation, but it's raising the following error:
File "/path/to/bettermod/bettermod.py", line 10, in <module>
from . import errors
ModuleNotFoundError: No module named 'bettermod'
Edit: when debugging, I found that __name__ was equal to bettermod.bettermod
From docs:
Note that relative imports are based on the name of the current module.
I cannot tell you what is wrong with certainty, but there is a smell: bettermod package has a bettermod module. You want to do from bettermod.bettermod import MyBetterClass? I doubt it. In Python files ARE namespaces, so choosing your file and directory names is also an API design. Just keep that in mind.
I suspect the problem is masked by the name collision. Try this. If you run python in bettermod directory and say import bettermod you are importing bettermod\bettermod.py. And . is relative to the bettermod.py module. Now try to run python in directory above bettermod package directory. It will work because now . resolves to bettermod package.
Try:
import mymodule
mymodule.__file__
This will tell what mymodule is. For packages, it will show path to __init__.py. This will help you to orient yourself. Also look up PYHTONPATH and how you can use it to make sure you are importing from the right path.
I have this file structure:
/home/test
├── dirA
│ └── ClassA.py
└── dirB
└── Main.py
With the following content in the files:
ClassA.py:
class ClassA:
def __str__(self):
return 'Hi'
Main.py:
from dirA.ClassA import ClassA
class Main:
def main():
a = ClassA()
if __name__ == '__main__':
Main.main()
I change the current dir to:
$ cd /home/test/dirB
This works:
$ PYTHONPATH=/home/test python Main.py
This doesn't:
$ python Main.py
Traceback (most recent call last):
File "Main.py", line 1, in <module>
from dirA.ClassA import ClassA
ModuleNotFoundError: No module named 'dirA'
Adding this lines in Main.py has no effect:
import os, sys
# Get the top level dir.
path = os.path.dirname(os.path.dirname(__file__))
sys.path.append(path)
The module still can't be found! There are plenty of similar questions but I couldn't make this work programmatically (skipping the PYTHONPATH env var.) I understand that dirs are not modules, files are but this works in PyCharm (is the IDE fixing PYTHONPATH?)
You need to make sure that you've altered your sys.path before you attempt to load any package that might depend on the altered path - otherwise your script will fail the moment it encounters and import statement. In other words, make sure your Main.py begins as:
import os
import sys
path = os.path.join(os.path.dirname(__file__), os.pardir)
sys.path.append(path)
from dirA.ClassA import ClassA
To ensure that the last import statement operates on the altered path.
Thanks for all the help. Per suggestion, I added the appended path as the first statement. That still didn't work. But then I used:
sys.path.append(sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
And this suddenly worked. Still not sure why the abspath makes a difference as the printed path I got was already absolute for __file__.
Building on the answer given by #zwer, we need to check if the script is being run in interactive mode or not. If it is, then we can use the approach mentioned by #zwer. If it is not, we can use the hard coded way (which is not always foolproof.
# https://stackoverflow.com/questions/16771894/python-nameerror-global-name-file-is-not-defined
if '__file__' in vars():
print("We are running the script non interactively")
path = os.path.join(os.path.dirname(__file__), os.pardir)
sys.path.append(path)
else:
print('We are running the script interactively')
sys.path.append("..")
Professional Python newbie here. I have created a Python module called aviation with a file in there called database.py.
I have another module called core, with a file in there called calculator.py.
I want to import aviation.database.py into my calculator.py.
The basic structure is as follows:
My project
aviation (module)
- database.py
core (module)
- calculator.py
test.py
My calculator.py file has an import such as:
from aviation import database as aviation_database
This module is not recognised and I get a red squiggly line indicating as much.
If I create another file test.py outside of aviation and core and add the above import, there are no issues in this tests.py file - the import works fine.
It appears that I need to do something so that my module can import from another module... it does allow me to import installed modules (like date), but I have no idea what I am missing.
I am using the IntelliJ IDE and my code is located in the regular C:\Users\\IdeaProjects directory.
Can someone tell me what I should do and why I am facing this problem?
Well I would recommend you to create __init__ file in the modules.
The python3 doc states that :
The __init__.py files are required to make Python treat the
directories as containing packages; this is done to prevent
directories with a common name, such as string, from unintentionally
hiding valid modules that occur later on the module search path. In
the simplest case, init.py can just be an empty file, but it can
also execute initialization code for the package or set the all
variable, described later.
So your Directory Structure becomes
My project
aviation (module)
- database.py
- __init__.py
core (module)
- calculator.py
- __init__.py
test.py
Now import all the thing in your __init__ file that you want to us from other packages. Like in aviation's __init__.py file write
import database
Similarly, for core's __init__.py
Now in calculator.py you can import them by -
from aviation import database
Let me know, if this help !
Thanks
Its as simple as this.
For instance, you have an already written code e.g myname.py and you want to import the entire module into new code e.g newwork.py
step 1. open your code newwork.py
step 2. just as you do other import, just write:
import myname
myname
Thats all.
Now, you have your entire nyname code inside newwork. When you run newwork, it runs nymame alongside.
I hope this help somebody?