Python3 içe aktarma deyimindeki değişiklikler


177

Pep-0404'ten aşağıdakileri anlamıyorum

Python 3'te, paketler içindeki örtük göreli içe aktarmalar artık mevcut değildir - yalnızca mutlak ithalatlar ve açık göreli içe aktarmalar desteklenmektedir. Buna ek olarak, yalnızca modül seviye kodunda yıldız içe aktarma işlemlerine (örneğin, x içe aktarma *) izin verilir.

Göreli ithalat nedir? Başka hangi yerlerde python2'de yıldız içe aktarmaya izin verildi? Lütfen örneklerle açıklayınız.

Yanıtlar:


277

Göreli içe aktarma, bir paketi geçerli komut dosyasına / pakete göre içe aktardığınızda gerçekleşir.

Örneğin aşağıdaki ağacı düşünün:

mypkg
├── base.py
└── derived.py

Şimdi, bir derived.pyşey istiyorsun base.py. Python 2'de şu şekilde yapabilirsiniz derived.py:

from base import BaseThing

Python 3 artık bunu desteklemiyor çünkü 'göreli' veya 'mutlak' isteyip istemediğiniz açık değil base. Başka bir deyişle, basesistemde yüklü bir Python paketi olsaydı, yanlış olanı alırsınız.

Bunun yerine , bir modülün konumunu yol bazında açıkça belirten açık içe aktarmalar kullanmanızı gerektirir . Sizin derived.pygibi görünecektir:

from .base import BaseThing

Lider .' basemodül dizininden içe aktar' diyor ; başka bir deyişle, ile .baseeşleşir ./base.py.

Benzer şekilde, ..dizin hiyerarşisini yukarı ../( ..modeşleme ile ../mod.py) yapan ve sonra ...iki düzey yukarı ( ../../mod.py) ve benzeri devam eden bir önek vardır .

Ancak, yukarıda listelenen göreli yolların , geçerli çalışma dizinine değil , geçerli modülün ( derived.py) bulunduğu dizine göreli olduğuna dikkat edin .


@BrenBarn zaten yıldız alma durumunu açıkladı. Tamlık için aynı şeyi söylemek zorundayım;).

Örneğin, birkaç mathişlev kullanmanız gerekir, ancak bunları yalnızca tek bir işlevde kullanırsınız. Python 2'de yarı tembel olmanıza izin verildi:

def sin_degrees(x):
    from math import *
    return sin(degrees(x))

Python 2'de zaten bir uyarıyı tetiklediğini unutmayın:

a.py:1: SyntaxWarning: import * only allowed at module level
  def sin_degrees(x):

Modern Python 2 kodunda ve Python 3'te aşağıdakilerden birini yapmanız gerekir:

def sin_degrees(x):
    from math import sin, degrees
    return sin(degrees(x))

veya:

from math import *

def sin_degrees(x):
    return sin(degrees(x))

14

Göreli ithalatlar için belgelere bakın . Göreli bir içe aktarma, bir modülden kesinlikle yerine yerine o modülün konumuna göre içe aktardığınız zamandır sys.path.

Gelince import *örneğin fonksiyonları içinde Python 2 izin yıldız ithalatı,:

>>> def f():
...     from math import *
...     print sqrt

Bunun için Python 2'de bir uyarı verilir (en azından son sürümler). Python 3'te artık izin verilmiyor ve yalnızca modülün en üst düzeyinde yıldız içe aktarma yapabilirsiniz (işlevlerin veya sınıfların içinde değil).


6
Bu karar neden verildi?
Dor

1
Tahminimce arkasındaki fikir 'Açık, örtük olmaktan iyidir.' PEP20 - Python Zen. Modülden önce nokta, göreli / ilişkisel olmayan bağlantıyı açıkça yapar ve böylece olası ad çakışmalarını çözer. 'Okunabilirlik önemlidir.' biraz acı çekiyor.
Pafnucy

2
Hayır, aslında "zıt", pratiklik saflığı yener kararıydı. Bu, işlevler içindeki yerel değişken erişimi optimize etmek için gerekliydi, çünkü "import *" olmadan derleyici her zaman sadece kodu analiz ederek, hangi değişkenlerin yerel olduğunu ve doğrudan aranabileceğini bilir. Aslında, işlevler yerel depolama için bir dikte kullanmaz, değişkenlerin benzersiz indeksler aldığı optimize edilmiş bir dizi kullanır.
Veky

11

Hem Python 2 hem de Python 3'ü desteklemek için aşağıdaki gibi açık göreli içe aktarmalar kullanın. Mevcut modüle göredir. 2.5'ten başlayarak desteklenmiştir .

from .sister import foo
from . import brother
from ..aunt import bar
from .. import uncle

14
import .brother bana Python 3.5'te geçersiz bir sözdizimi hatası veriyor. Bu normal? İçinde bulunduğum dizinde init .py var
Frikster

1
import .brother2 ve 3 için geçersiz sözdizimi
Rodrigo E. Principe

@ RodrigoE.Principe ve öyle görünüyor import ..uncle. Sabit. Oh, ne düşünüyordum ... muhtemelen Ni diyen şövalyelerin dikkatini dağıttı!
Akseli Palén

4

Michał Górny'nin cevabına bir dava daha ekledi:

Göreli içe aktarma işlemlerinin geçerli modülün adını temel aldığını unutmayın. Ana modülün adı her zaman " __main__" olduğundan, bir Python uygulamasının ana modülü olarak kullanılması amaçlanan modüllerin her zaman mutlak ithalatları kullanması gerekir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.