目录
Option 2: Just Make an Actual Package
I met with an import error when using python, which said " attemped relative import with no known parent package". I am not very familiar with python, after searching, I found the autor of the following article gives a detailed explanation.
ImportError: attempted relative import with no known parent packagehttps://iq-inc.com/importerror-attempted-relative-import/
The author's case
This issue almost always occurs because you are using a flat file structure for your project, and you try to split the functionality into two files. For example:
# file structure
.
└── src/
├── main.py
└── util.py
###########################
# main.py
from util import doSomethingCool
print("About to do something cool!")
doSomethingCool()
##########################################
# util.py
def doSomethingCool():
print("Doing something cool")
Running main.py with this setup will result in:
ImportError: attempted relative import with no known parent package
Option 1: Get Rid of From
Don’t use from
and just use import
, then make sure you use the module reference when using your imported functions. In our example, this is util
. So your main.py would now look like this:
# main.py
import util
print("About to do something cool!")
util.doSomethingCool()
Problem solved.
Option 2: Just Make an Actual Package
If you are making a separate file to do helpful things, why not make it an actual package? It is actually much easier than you would think.
Change up your file structure so that the functionality you want to split out is in a separate folder and includes an empty __init__.py
file. Something like this:
. └── src/ ├── main.py └── utils/ ├── __init__.py └── util.py
With this structure, you can actually import in many different ways. Any of the following will work.
# Main file for doing cool things
import utils.util
print("About to do something cool!")
utils.util.doSomethingCool()
# Main file for doing cool things
from utils import util
print("About to do something cool!")
util.doSomethingCool()
# Main file for doing cool things
from utils.util import doSomethingCool
print("About to do something cool!")
doSomethingCool()
You can also get extra fancy and use the as
keyword, which will let you define a new alias for your import.
# Main file for doing cool things
import utils.util as foo
print("About to do something cool!")
foo.doSomethingCool()
What’s a Module?
What do you do when you make a function that you want to use in multiple scripts? This is where we use a module. A module is simply a .py
script that contains one or more definitions. Definitions are functions that we define in a module that can be used in other scripts via the import
keyword.
The file name becomes the module name. So, for example, if we have foo.py
we would import that using import foo
. Basic modules tend to work best when they are in the same directory as your main script.
When you use the import
keyword, for example, import foo
, python will load that script and bring all of the definitions into your current script. The functions are not imported directly into the script, but they are accessible via the module name.
# foo.py
barJoke = "E-Flat walks into a bar. The bartender says, 'Sorry, we don't serve minors!'"
def bar():
print(barJoke)
# main.py
import foo
foo.bar()
Modules let you logically separate your code into functional pieces. You can also include code that is not a function definition when importing a module. It is only executed once when the module is first imported. See the example below that initializes barJoke
when imported.
What’s a Package?
A package is a mechanism to bundle one or more modules in a way that makes them easier to organize into logical groups. Packages also allow us to organize our modules into different folders. If you find yourself with more than a handful of modules, it is probably time to use a package. This article will not cover distributing packages. If you want to learn more about package distribution check out the doc page for Python Wheels.
In its simplest form, any directory that has an __init__.py
file and one or more modules is a package.
The __init__.py
file serves as both a marker for python that this is a package and also a place to execute any initialization code required to use the package. Typically __init__.py
is just an empty file unless you need to do some form of advanced package initialization.
You can also have multiple packages in the same parent folder. You can even have nested packages:
.
└── src/
├── main.py
├── utils/
│ ├── __init__.py
│ ├── util.py
│ └── shared/
│ ├── __init__.py
│ └── helpers.py
└── calculations/
├── __init__.py
└── financials.py