__future__ import mutlak_import’tan gerçekte ne yapar?

| | | | | | | | |

Python'daki mutlak içe aktarmalarla ilgili bir soruyu cevapladım ve Python 2.5 değişiklik günlüğü ve beraberindeki PEP. Bununla birlikte, Python 2.5'i yükledikten ve from __future__ import mutlak_import kullanarak düzgün bir örnek oluşturmaya çalıştıktan sonra, işlerin o kadar net olmadığını fark ettim.

Yukarıda bağlantı verilen değişiklik günlüğünden doğrudan, bu ifadesi, mutlak içe aktarma değişikliği konusundaki anlayışımı doğru bir şekilde özetledi:

Diyelim ki şöyle bir paket dizininiz var:

pkg/ pkg/__init__.py pkg/main.py pkg/string.py 

Bu, pkg.main ve içeren pkg adlı bir paketi tanımlar. pkg.string alt modülleri.

Main.py modülündeki kodu düşünün. import string ifadesini çalıştırırsa ne olur? Python 2.4 ve önceki sürümlerde, göreli bir içe aktarma gerçekleştirmek için önce paketin dizinine bakar, pkg/string.py'yi bulur, bu dosyanın içeriğini pkg.string modülü olarak içe aktarır ve bu modül ada bağlıdır pkg.main modülünün adlarında "string" tempo.

Bu yüzden tam olarak bu dizin yapısını oluşturdum:

$ ls -R .: pkg/ ./pkg: __init__.py main.py string .py 

__init__.py ve string.py boş. main.py aşağıdaki kodu içerir:

dizeyi içe aktar print string.ascii_uppercase 

Beklendiği gibi, bunu Python 2.5 ile çalıştırıyor AttributeError ile başarısız oluyor:

$ python2.5 pkg/main.py Geri izleme (en son çağrı son): Dosya "pkg/main.py", satır 2 , <modül> print string.ascii_uppercase AttributeError: "module" nesnesinin "ascii_uppercase" özniteliği yoktur 

Ancak, 2.5 değişiklik günlüğünün devamında şunu buluruz (vurgu eklenmiştir):

Python 2.5'te, from __future__ import mutlak_import yönergesini kullanarak import" davranışını mutlak içe aktarma olarak değiştirebilirsiniz. gelecekteki bir sürüm (muhtemelen Python 2.7). Mutlak içe aktarma varsayılan olduğunda, içe aktarma dizesi her zaman standart kitaplığın sürümünü bulur.

Böylece main.py ile aynı, ancak gelecekteki içe aktarma yönergesiyle pkg/main2.py'u oluşturdum. Şimdi şuna benziyor:

__future__'den içe mutlak_import içe aktarma dizesi yazdırma dizesi.ascii_uppercase 

Bunu Python 2.5 ile çalıştırmak, ancak... AttributeError:

$ python2.5 pkg/main2.py Geri izleme (en son çağrı son): Dosya "pkg/main2.py", satır 3, < ;modül> print string.ascii_uppercase AttributeError: "module" nesnesinin "ascii_uppercase" özniteliği yok 

Bu, import string'in her zaman alacağı ifadesiyle tamamen çelişiyor güçlü> mutlak içe aktarmanın etkin olduğu std-lib sürümünü bulun. Dahası, mutlak içe aktarmanın "yeni varsayılan" davranış olarak planlandığı uyarısına rağmen, aynı sorunu __future__ yönergesi olsun ya da olmasın Python 2.7'yi kullanarak buldum:

$ python2.7 pkg/main.py Geri İzleme (en son çağrı son): Dosya "pkg/main.py", satır 2, <module> print string.ascii_uppercase AttributeError: "module" nesnesi "ascii_uppercase" özniteliği yok $ python2.7 pkg/main2.py Geri izleme (en son çağrı son): Dosya "pkg/main2.py", satır 3, <module> print string.ascii_uppercase AttributeError: "module" nesnesi "ascii_uppercase" 

ve Python 3.5'in yanı sıra, olsun veya olmasın (print ifadesinin her iki dosyada da değiştirildiği varsayılarak):

$ python3.5 pkg/main.py Geri İzleme (en son çağrı son): Dosya "pkg/main.py", satır 2, <module> print(string.ascii_uppercase) AttributeError: module "string " "ascii_uppercase" özniteliğine sahip değil $ python3.5 pkg/main2.py Trac eback (en son arama son): Dosya "pkg/main2.py", satır 3, <module> print(string.ascii_uppercase) AttributeError: "string" modülünün "ascii_uppercase" özniteliği yok 

Bunun diğer varyasyonlarını test ettim. string.py yerine boş bir modül oluşturdum -- string adında yalnızca boş bir __init__.py içeren bir dizin -- ve bunun yerine main.py'dan içe aktarma yayınlamak için, cd"d - pkg'a sahibim ve içe aktarmaları doğrudan REPL'den çalıştırıyorum. Bu varyasyonların hiçbiri (ne de bunların bir kombinasyonu) yukarıdaki sonuçları değiştirdi. Bunu __future__ yönergesi ve mutlak ithalat hakkında okuduklarım ile bağdaştıramıyorum.

Bana bu kolayca açıklanabilir gibi geliyor. aşağıdaki tarafından (bu, Python 2 belgelerine aittir, ancak bu ifadesi Python 3) için aynı belgelerde değişmeden kalır:

sys.path

(...)

Program başlatıldığında başlatıldığı gibi, bu listenin ilk öğesi, path[0], Python yorumlayıcısını çağırmak için kullanılan komut dosyasını içeren dizindir. y kullanılamaz (örneğin, yorumlayıcı etkileşimli olarak çağrılırsa veya komut dosyası standart girdiden okunursa), path[0] boş dizedir, Python'u önce geçerli dizin.

Peki neyi kaçırıyorum? __future__ ifadesi neden söylediğini yapmıyor ve bu iki belge bölümü arasındaki ve ayrıca açıklanan ve gerçek davranış arasındaki bu çelişkinin çözümü nedir?

Shop

Learn programming in R: courses

$

Best Python online courses for 2022

$

Best laptop for Fortnite

$

Best laptop for Excel

$

Best laptop for Solidworks

$

Best laptop for Roblox

$

Best computer for crypto mining

$

Best laptop for Sims 4

$

Latest questions

NUMPYNUMPY

psycopg2: insert multiple rows with one query

12 answers

NUMPYNUMPY

How to convert Nonetype to int or string?

12 answers

NUMPYNUMPY

How to specify multiple return types using type-hints

12 answers

NUMPYNUMPY

Javascript Error: IPython is not defined in JupyterLab

12 answers


Wiki

Python OpenCV | cv2.putText () method

numpy.arctan2 () in Python

Python | os.path.realpath () method

Python OpenCV | cv2.circle () method

Python OpenCV cv2.cvtColor () method

Python - Move item to the end of the list

time.perf_counter () function in Python

Check if one list is a subset of another in Python

Python os.path.join () method