关于python模块循环导入(circular imports)/相对导入(Relative Imports)/绝对导入(Absolute Imports)的官方资料

来源:互联网 发布:gap淘宝旗舰店 编辑:程序博客网 时间:2024/04/29 17:15

In general, don’t usefrom modulename import*.Doing so clutters the importer’s namespace. Some peopleavoid this idiom even with the few modules that were designed to be imported in this manner. Modules designed inthis manner includeTkinter,andthreading.

Import modules at the top of a file. Doing so makes it clear what other modules your code requires and avoids questionsof whether the module name is in scope. Using one import per line makes it easy to add and delete module imports,but using multiple imports per line uses less screen space.

It’s good practice if you import modules in the following order:

1. standard library modules – e.g.sys, os, getopt, re

2. third-party library modules (anything installed in Python’s site-packages directory) – e.g. mx.DateTime, ZODB,PIL.Image, etc.

3. locally-developed modules

Never use relative package imports.If you’re writing code that’s in thepackage.sub.m1module and want toimportpackage.sub.m2,do not just writeimport m2,even though it’s legal. Write from package.sub import m2 instead.Relative imports can lead to a module being initialized twice, leading to confusing bugs. SeePEP 328for details.

It is sometimes necessary to move imports to a function or class to avoid problems with circular imports. GordonMcMillan says:

Circular imports are fine where both modules use the “import <module>” form of import. They fail whenthe 2nd module wants to grab a name out of the first (“from module import name”) and the import is at thetop level. That’s because names in the 1st are not yet available, because the first module is busy importingthe 2nd.

In this case, if the second module is only used in one function, then the import can easily be moved into that function.By the time the import is called, the first module will have finished initializing, and the second module can do itsimport.

It may also be necessary to move imports out of the top level of code if some of the modules are platform-specific.In that case, it may not even be possible to import all of the modules at the top of the file. In this case, importing thecorrect modules in the corresponding platform-specific code is a good option.

Only move imports into a local scope, such as inside a function definition, if it’s necessary to solve a problem suchas avoiding a circular import or are trying to reduce the initialization time of a module. This technique is especiallyhelpful if many of the imports are unnecessary depending on how the program executes. You may also want to moveimports into a function if the modules are only ever used in that function. Note that loading a module the first time maybe expensive because of the one time initialization of the module, but loading a module multiple times is virtually free,costing only a couple of dictionary lookups. Even if the module name has gone out of scope, the module is probablyavailable in sys.modules.

If only instances of a specific class use a module, then it is reasonable to import the module in the class’s__init__method and then assign the module to an instance variable so that the module is always available (via that instancevariable) during the life of the object. Note that to delay an import until the class is instantiated, the import must beinside a method. Putting the import inside the class but outside of any method still causes the import to occur whenthe module is initialized. 



PEP 328:

Abstract

The import statement has two problems:

  • Long import statements can be difficult to write, requiring various contortions to fit Pythonic style guidelines.
  • Imports can be ambiguous in the face of packages; within a package, it's not clear whether import foo refers to a module within the package or some module outside the package. (More precisely, a local module or package can shadow another hanging directly off sys.path.)

For the first problem, it is proposed that parentheses be permitted to enclose multiple names, thus allowing Python's standard mechanisms for multi-line values to apply. For the second problem, it is proposed that all import statements be absolute by default (searching sys.path only) with special syntax (leading dots) for accessing package-relative imports.

Timeline

In Python 2.5, you must enable the new absolute import behavior with

from __future__ import absolute_import

You may use relative imports freely. In Python 2.6, any import statement that results in an intra-package import will raise DeprecationWarning (this also applies to from <> import that fails to use the relative import syntax).

Rationale for Parentheses

Currently, if you want to import a lot of names from a module or package, you have to choose one of several unpalatable options:

  • Write a long line with backslash continuations:

    from Tkinter import Tk, Frame, Button, Entry, Canvas, Text, \    LEFT, DISABLED, NORMAL, RIDGE, END
  • Write multiple import statements:

    from Tkinter import Tk, Frame, Button, Entry, Canvas, Textfrom Tkinter import LEFT, DISABLED, NORMAL, RIDGE, END

(import * is not an option ;-)

Instead, it should be possible to use Python's standard grouping mechanism (parentheses) to write the import statement:

from Tkinter import (Tk, Frame, Button, Entry, Canvas, Text,    LEFT, DISABLED, NORMAL, RIDGE, END)

This part of the proposal had BDFL approval from the beginning.

Parentheses support was added to Python 2.4.

Rationale for Absolute Imports

In Python 2.4 and earlier, if you're reading a module located inside a package, it is not clear whether

import foo

refers to a top-level module or to another module inside the package. As Python's library expands, more and more existing package internal modules suddenly shadow standard library modules by accident. It's a particularly difficult problem inside packages because there's no way to specify which module is meant. To resolve the ambiguity, it is proposed that foo will always be a module or package reachable from sys.path. This is called an absolute import.

The python-dev community chose absolute imports as the default because they're the more common use case and because absolute imports can provide all the functionality of relative (intra-package) imports -- albeit at the cost of difficulty when renaming package pieces higher up in the hierarchy or when moving one package inside another.

Because this represents a change in semantics, absolute imports will be optional in Python 2.5 and 2.6 through the use of

from __future__ import absolute_import

This part of the proposal had BDFL approval from the beginning.

Rationale for Relative Imports

With the shift to absolute imports, the question arose whether relative imports should be allowed at all. Several use cases were presented, the most important of which is being able to rearrange the structure of large packages without having to edit sub-packages. In addition, a module inside a package can't easily import itself without relative imports.

Guido approved of the idea of relative imports, but there has been a lot of disagreement on the spelling (syntax). There does seem to be agreement that relative imports will require listing specific names to import (that is, import foo as a bare term will always be an absolute import).

Here are the contenders:

  • One from Guido:

    from .foo import bar

    and

    from ...foo import bar

    These two forms have a couple of different suggested semantics. One semantic is to make each dot represent one level. There have been many complaints about the difficulty of counting dots. Another option is to only allow one level of relative import. That misses a lot of functionality, and people still complained about missing the dot in the one-dot form. The final option is to define an algorithm for finding relative modules and packages; the objection here is "Explicit is better than implicit". (The algorithm proposed is "search up from current package directory until the ultimate package parent gets hit".)

    Some people have suggested other punctuation as the separator, such as "-" or "^".

    Some people have suggested using "*":

    from *.foo import bar
  • The next set of options is conflated from several posters:

    from __pkg__.__pkg__ import

    and

    from .__parent__.__parent__ import

    Many people (Guido included) think these look ugly, but they are clear and explicit. Overall, more people prefer __pkg__ as the shorter option.

  • One suggestion was to allow only sibling references. In other words, you would not be able to use relative imports to refer to modules higher in the package tree. You would then be able to do either

    from .spam import eggs

    or

    import .spam.eggs
  • Some people favor allowing indexed parents:

    from -2.spam import eggs

    In this scenario, importing from the current directory would be a simple

    from .spam import eggs
  • Finally, some people dislike the way you have to change import to from ... import when you want to dig inside a package. They suggest completely rewriting the import syntax:

    from MODULE import NAMES as RENAME searching HOW

    or

    import NAMES as RENAME from MODULE searching HOW    [from NAMES] [in WHERE] import ...

    However, this most likely could not be implemented for Python 2.5 (too big a change), and allowing relative imports is sufficiently critical that we need something now (given that the standard import will change to absolute import). More than that, this proposed syntax has several open questions:

    • What is the precise proposed syntax? (Which clauses are optional under which circumstances?)

    • How strongly does the searching clause bind? In other words, do you write:

      import foo as bar searching XXX, spam as ham searching XXX

      or:

      import foo as bar, spam as ham searching XXX

Guido's Decision

Guido has Pronounced [1] that relative imports will use leading dots. A single leading dot indicates a relative import, starting with the current package. Two or more leading dots give a relative import to the parent(s) of the current package, one level per dot after the first. Here's a sample package layout:

package/    __init__.py    subpackage1/        __init__.py        moduleX.py        moduleY.py    subpackage2/        __init__.py        moduleZ.py    moduleA.py

Assuming that the current file is either moduleX.py or subpackage1/__init__.py, following are correct usages of the new syntax:

from .moduleY import spamfrom .moduleY import spam as hamfrom . import moduleYfrom ..subpackage1 import moduleYfrom ..subpackage2.moduleZ import eggsfrom ..moduleA import foofrom ...package import barfrom ...sys import path

Note that while that last case is legal, it is certainly discouraged ("insane" was the word Guido used).

Relative imports must always use from <> importimport <> is always absolute. Of course, absolute imports can use from <> import by omitting the leading dots. The reason import .foo is prohibited is because after

import XXX.YYY.ZZZ

then

XXX.YYY.ZZZ

is usable in an expression. But

.moduleY

is not usable in an expression.

Relative Imports and __name__

Relative imports use a module's __name__ attribute to determine that module's position in the package hierarchy. If the module's name does not contain any package information (e.g. it is set to '__main__') then relative imports are resolved as if the module were a top level module, regardless of where the module is actually located on the file system.

Relative Imports and Indirection Entries in sys.modules

When packages were introduced, the concept of an indirection entry in sys.modules came into existence [2]. When an entry in sys.modules for a module within a package had a value of None, it represented that the module actually referenced the top-level module. For instance, 'Sound.Effects.string' might have a value of None in sys.modules. That meant any import that resolved to that name actually was to import the top-level 'string' module.

This introduced an optimization for when a relative import was meant to resolve to an absolute import. But since this PEP makes a very clear delineation between absolute and relative imports, this optimization is no longer needed. When absolute/relative imports become the only import semantics available then indirection entries in sys.modules will no longer be supported.

References

For more background, see the following python-dev threads:

  • Re: Christmas Wishlist
  • Re: Python-Dev Digest, Vol 5, Issue 57
  • Relative import
  • Another Strategy for Relative Import
[1]http://mail.python.org/pipermail/python-dev/2004-March/043739.html[2]http://www.python.org/doc/essays/packages.html

原创粉丝点击