Movatterモバイル変換


[0]ホーム

URL:


Following system colour schemeSelected dark colour schemeSelected light colour scheme

Python Enhancement Proposals

PEP 328 – Imports: Multi-Line and Absolute/Relative

Author:
Aahz <aahz at pythoncraft.com>
Status:
Final
Type:
Standards Track
Created:
21-Dec-2003
Python-Version:
2.4, 2.5, 2.6
Post-History:
08-Mar-2004

Table of Contents

Abstract

Theimport statement has two problems:

  • Longimport statements can be difficult to write, requiringvarious contortions to fit Pythonic style guidelines.
  • Imports can be ambiguous in the face of packages; within a package,it’s not clear whetherimportfoo refers to a module within thepackage or some module outside the package. (More precisely, a localmodule or package can shadow another hanging directly offsys.path.)

For the first problem, it is proposed that parentheses be permitted toenclose multiple names, thus allowing Python’s standard mechanisms formulti-line values to apply. For the second problem, it is proposed thatallimport statements be absolute by default (searchingsys.pathonly) with special syntax (leading dots) for accessing package-relativeimports.

Timeline

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

from__future__importabsolute_import

You may use relative imports freely. In Python 2.6, anyimportstatement that results in an intra-package import will raiseDeprecationWarning (this also applies tofrom<>import thatfails to use the relative import syntax).

Rationale for Parentheses

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

  • Write a long line with backslash continuations:
    fromTkinterimportTk,Frame,Button,Entry,Canvas,Text, \LEFT,DISABLED,NORMAL,RIDGE,END
  • Write multipleimport statements:
    fromTkinterimportTk,Frame,Button,Entry,Canvas,TextfromTkinterimportLEFT,DISABLED,NORMAL,RIDGE,END

(import* isnot an option ;-)

Instead, it should be possible to use Python’s standard groupingmechanism (parentheses) to write theimport statement:

fromTkinterimport(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 apackage, it is not clear whether

importfoo

refers to a top-level module or to another module inside the package.As Python’s library expands, more and more existing package internalmodules suddenly shadow standard library modules by accident. It’s aparticularly difficult problem inside packages because there’s no way tospecify which module is meant. To resolve the ambiguity, it is proposedthatfoo will always be a module or package reachable fromsys.path. This is called an absolute import.

The python-dev community chose absolute imports as the default becausethey’re the more common use case and because absolute imports can provideall the functionality of relative (intra-package) imports – albeit atthe cost of difficulty when renaming package pieces higher up in thehierarchy or when moving one package inside another.

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

from__future__importabsolute_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 whetherrelative imports should be allowed at all. Several use cases werepresented, the most important of which is being able to rearrange thestructure of large packages without having to edit sub-packages. Inaddition, a module inside a package can’t easily import itself withoutrelative imports.

Guido approved of the idea of relative imports, but there has been alot of disagreement on the spelling (syntax). There does seem to beagreement that relative imports will require listing specific names toimport (that is,importfoo as a bare term will always be anabsolute import).

Here are the contenders:

  • One from Guido:
    from.fooimportbar

    and

    from...fooimportbar

    These two forms have a couple of different suggested semantics. Onesemantic is to make each dot represent one level. There have beenmany complaints about the difficulty of counting dots. Anotheroption is to only allow one level of relative import. That misses alot of functionality, and people still complained about missing thedot in the one-dot form. The final option is to define an algorithmfor 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 packageparent gets hit”.)

    Some people have suggested other punctuation as the separator, suchas “-” or “^”.

    Some people have suggested using “*”:

    from*.fooimportbar
  • 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 theyareclear and explicit. Overall, more people prefer__pkg__ as theshorter option.

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

    or

    import.spam.eggs
  • Some people favor allowing indexed parents:
    from-2.spamimporteggs

    In this scenario, importing from the current directory would be asimple

    from.spamimporteggs
  • Finally, some people dislike the way you have to changeimporttofrom...import when you want to dig inside a package. Theysuggest completely rewriting theimport syntax:
    fromMODULEimportNAMESasRENAMEsearchingHOW

    or

    importNAMESasRENAMEfromMODULEsearchingHOW[fromNAMES][inWHERE]import...

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

    • What is the precise proposed syntax? (Which clauses are optionalunder which circumstances?)
    • How strongly does thesearching clause bind? In other words,do you write:
      importfooasbarsearchingXXX,spamashamsearchingXXX

      or:

      importfooasbar,spamashamsearchingXXX

Guido’s Decision

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

package/__init__.pysubpackage1/__init__.pymoduleX.pymoduleY.pysubpackage2/__init__.pymoduleZ.pymoduleA.py

Assuming that the current file is eithermoduleX.py orsubpackage1/__init__.py, following are correct usages of the newsyntax:

from.moduleYimportspamfrom.moduleYimportspamashamfrom.importmoduleYfrom..subpackage1importmoduleYfrom..subpackage2.moduleZimporteggsfrom..moduleAimportfoofrom...packageimportbarfrom...sysimportpath

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

Relative imports must always usefrom<>import;import<> isalways absolute. Of course, absolute imports can usefrom<>importby omitting the leading dots. The reasonimport.foo is prohibitedis because after

importXXX.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 thatmodule’s position in the package hierarchy. If the module’s name doesnot contain any package information (e.g. it is set to ‘__main__’)then relative imports are resolved as if the module were a top levelmodule, regardless of where the module is actually located on the filesystem.

Relative Imports and Indirection Entries in sys.modules

When packages were introduced, the concept of an indirection entry insys.modules came into existence[2]. When an entry in sys.modulesfor a module within a package had a value of None, it represented thatthe 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 toimport the top-level ‘string’ module.

This introduced an optimization for when a relative import was meantto resolve to an absolute import. But since this PEP makes a veryclear delineation between absolute and relative imports, thisoptimization is no longer needed. When absolute/relative importsbecome the only import semantics available then indirection entries insys.modules will no longer be supported.

References

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

[1]
https://mail.python.org/pipermail/python-dev/2004-March/043739.html
[2]
https://www.python.org/doc/essays/packages/

Copyright

This document has been placed in the public domain.


Source:https://github.com/python/peps/blob/main/peps/pep-0328.rst

Last modified:2025-02-01 08:59:27 GMT


[8]ページ先頭

©2009-2025 Movatter.jp