Python vs. Package Import Report "Attempted relative import in Non-package" error

Source: Internet
Author: User

Using relative package import in Python sometimes is a very painful thing, sometimes using the relative package import clearly can be in operation, but changed a way of operation is not possible. This article is going to solve this problem in depth, in the process of looking at the code to continue to practice, understand Python relative package import.

This article was translated from StackOverflow.

Relative imports for the billionth time

Problem Description

In order to solve this problem, I searched the website, of course, there are more sites

    • http://www.python.org/dev/peps/pep-0328/
    • Http://docs.python.org/2/tutorial/modules.html#packages
    • Python Packages:relative Imports
    • Python Relative Import example code does not work
    • Ultimate answer to relative Python imports
    • Relative Imports in Python
    • Python:disabling Relative Import

The problem is this, on the win7,32 computer, run python2.7.3, how to solve the "attempted relative import in Non-package" issue. I set up a directory structure based on pep-0328.

package/

__init__.py

subpackage1/

__init__.py

modulex.py

moduley.py

subpackage2/

__init__.py

modulez.py

modulea.py

and according to the requirements of this directory, the spam and eggs functions are established. Obviously, when I ran it, he didn't run successfully. There may be some answers to the fourth URL I have listed, but I can't understand it. The message inside that URL is this:

relative imports use the module's Name property to determine the location of the module in the package hierarchy, if the module name does not contain any package information (for example: set to ' Main '), then the relative import is parsed to the topmost position, regardless of where the module is actually located in the filesystem.

The above answer seems a little hopeful, but for me it's a little bit understandable. So, my question is: How do I run a python program that no longer returns "attempted relative import in Non-package" while explaining the-M option.

Is there anyone who can tell me why Python reported this error, what ' non-package ' means here, why and how to define a ' package '. Is there anyone who can tell me some simple answers so that I can understand some of the people I just started with?

Answer: scripting vs Modules (script vs module)

there is a big difference between running a file directly and importing it in another file, just knowing the location of a file in the directory does not imply where the Python program thinks it is. This is determined by how Python loads (runs or imports. Run or Import) this file.

Python has two ways to load files: One as the top-level script and the other as a module. If you execute the program directly, the file is executed as a top-level script, which is the case when you enter Python myfile.py on the command line. If you enter Python-m myfile.py or import this file in other files, it is imported as a module. At the same time, there is only one top-level script, and the top-level script is the concept: it is a python file that allows your program to start here.

"File is a non-discriminatory name, run directly from this file, then this file is called a script, import this file, then this file is the module." Package: is a directory that requires a __init__.py file. Modules are module, packages are package "

naming (naming)

when a file is loaded, it has a name (the name is stored in the __name__ attribute). If the file is loaded as a top-level script, its name is __main__ "That's why we often find such statements: if __name__ = =" __main__ ". If it is loaded as a module, its name is the name of the file, plus the package name it is in, and all the top-level package names, which are separated by dot numbers.

such as the following example

package/

__init__.py

subpackage1/

__init__.py

modulex.py

modulea.py

For example, you import Modulex (note: Import, not run directly), its name is Package.subpackage1.mouleX. If you import Modulea, its name is Package.moudlea. However, when you run Modulea directly from the command line, his name is replaced with __main__. If you run Modulea directly from the command line, its name is also __main__. When a module is executed as a top-level script, its original name is replaced by __main__.

do not access a module through a packet

Here's an extra question: The name of the module depends on whether it was imported directly from the directory in which it was located, or through a package. But this only happens when you run Python in a directory and try to import files from that directory . Note: Package import is a case where someone else encapsulates a package (containing a __init__.py file) that you directly use with the package name. Module name.

For example, if you open the Python interpreter in the Package/subpackage1 directory and then enter import Modulex, then the Modulex name is Modulex, Rather than Package.subpackage1.moduleX. This is because Python adds the current directory to the search path. If it finds the included module in the current directory, it will not know that the directory is also part of the module, and the package information will not appear in the module name.

A special case is this: when you run the Python interpreter directly (for example, enter Python on the command line and enter the Python interpreter, enter the code). In this case, the name of this interactive terminal is __main__.

Now, your question has a key answer: If there is no dot in the name of a module, it will not be considered a package. regardless of where this file is located on the disk. All that matters is what its name is, and the name depends on how you load it.

so now look at you in the other This quote from the URL:

relative imports use the module's Name property to determine the location of the module in the package hierarchy, if the module name does not contain any package information (for example: set to ' Main '), then the relative import is parsed to the topmost position, regardless of where the module is actually located in the filesystem.

Relative Import...

relative imports use the name of the module to determine its location in a package. When you use a relative import like this: from. Import foo, where the dot indicates a number of package levels rising in the package hierarchy. For example, now the module name is Package.subpackage1.moudleX, then: The two dots in the Modulea represent a rise of two packages, arriving at the package, and then combining with Modulea, eventually becoming Package.modulea. To get from. Import works correctly, and the module must have at least the same number of points as above in its name.

" For example: module name:a.b.c.d

the from. The import x represents an ascending layer and then a combination with X, which eventually becomes the a.b.c.x

From.. Import x is up two levels, reaching a.b and then combining with X, resulting in a.b.x "

... Can only be used in relative imports when using

if the name of your module is __main__, then it is not considered to be in a package, because its name does not contain a bit, so you cannot use from within it. Import If you use this statement, the program will report "Relative-import in Non-package" error.

scripts cannot contain relative imports:

when you run Modulex directly or run the program in the command line terminal, this time the module name is __main__, which indicates that you cannot use relative import. Because their names indicate that they are not in a package. Note: When you run a Python directory that is the directory where your module is located, this can also happen, in which case Python's premature search for the current directory's module does not consider them to be part of the package.

When you run an interactive interpreter, the name of the interactive process is always __main__, so you cannot use relative imports in the interactive process. Relative imports can only be used in module files.

Two solutions:

1: If you want to run Modulex directly, but you want to think of it as part of a package, you can use Python-m Package.subpackage.moduleX. The-m parameter tells Python to load it as a module rather than a top-level script.

2: Perhaps you do not want to run Modulex directly, you want to use the Modulex function in other scripts, for example, this script is myfile.py. If this is the case, you need to put the myfile.py somewhere else, not in the package directory. Use the statement in myfile.py to work properly: from Package.modulea import spam.

Note: for both of these cases, the package directory (such as the one above ) must exist under the Python search path (sys.path). If it does not exist, you will not be able to use anything in the package.

since python2.6, the name of the module is not determined using the __name__ property, but instead uses the __packege__ property. That's why I avoid using __name__ so explicit a name to represent the name of a module. Since python2.6, the name of a module is by __package__+ '. ' +__name__ to determine, if __packege__ is None, then the name is __name__.

Python vs. Package Import Report "Attempted relative import in Non-package" error

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.