Bir Python modülü syspath'a nasıl eklenir?


69

Bunun gibi bir dosya yapısına sahibim:

Folder
   Common
      foo1.py
   TestFolder
      foo2.py

Ben almak istiyorum foo2.py ve foo1.py. Denedim ama Ubuntu'da çalışmıyor:

sys.path.append(os.path.abspath('../../'))
from Common import foo1.py

__init__.pyKlasöründe bir dosya var mı? python nasıl paketler yaratır ve modülleri o paketten almanıza izin verir. guide.python-distribute.org/creation.html
Bryan

Ortak ve TestFolder'da init.py dosyam var
user284474

Eğer almak istiyorsanız, Klasör dizininde ve alt klasörlerde ihtiyacınız var
Bryan

Bu init .py boş mu?
user284474

1
evet boş olabilir. Paketiniz için belirli bir konfigürasyona ihtiyacınız olmadıkça, ancak boş olması gerektiğinden emin olmalısınız
Bryan

Yanıtlar:


115

Python modüllerini nasıl bulur?

Kesinlikle alındığında, bir modül tek bir python dosyasıdır, paket ise python dosyalarını __init__.pyalmak için bir paket olduğunu söylemek için adında bir (boş olabilir) dosya eşliğinde python dosyalarını içeren bir klasördür . Her iki durumda da, modüllerin .pyuzantılarına ihtiyacı vardır , ancak bunları içe aktarmadan yapılır (aşağıya bakınız).

Varsayılan olarak, Python içindeki modüllerini ve paketlerini arar $PYTHONPATH.

$ PYTHONPATH’da neler olduğunu bulmak için, aşağıdaki kodu python (3) ile çalıştırın:

import sys
print(sys.path)

Bir dizin nasıl eklenir

Bazen

Bir python dosyası içinden, python uygulamanızın veya komut dosyanızın baş bölümüne aşağıdaki satırları ekleyerek ara sıra varsayılan yola yol (lar) ekleyebilirsiniz:

import sys
sys.path.insert(0, "/path/to/your/package_or_module")

Örneğin:

eğer bir klasörüm varsa: /home/myname/pythonfilesve module_1.pyo dizinde bulunan dosyayı almak istiyorum , bunu kodumun baş kısmına ekliyorum:

import sys
sys.path.insert(0, "/home/myname/pythonfiles")

Ve sadece dosyayı kullanarak içe aktarabilirim module_1.py:

import module_1

Bir paket oluşturduğumda ve paketten modül (ler) almak istediğimde, içinde $PYTHONPATH(boş olabilir) bir dosya eşliğinde, modülleri içeren bir klasör oluşturmam gerekiyor__init__.py

Örneğin:

Adlı bir paketi (klasör) den almak için my_packagede /home/myname/pythonfileseklemek /home/myname/pythonfilesadresinden Müşteri yolunu $PYTHONPATHörnek 1'de olduğu gibi, ve denir modülü almak module_2.pybasitçe ile (paket klasörün içinde): `

from <packagename> import module_2

$PYTHONPATHKalıcı olarak dizin ekleme :

Dosyana aşağıdaki satırı ekleyin ~/.profile.

export PYTHONPATH=$PYTHONPATH:/path/you/want/to/add

Alt Dizinler

Bir paket içinde, alt dizinler bu şekilde dahil edilmez; Dizinleri "zincirlemeniz" gerekir. Bir modülü almak için module_3.py, klasörün subfolderiçindeki klasörün içine packagename:

import packagename.subfolder.module_3

Paketteki tüm alt klasörlerin kendi __init__.pydosyalarını içerdiği gerçeği göz önüne alındığında .

Bir modül, komut dosyası veya uygulama ile aynı dizinde olduğunda

Komut veya uygulama ile aynı dizinde olduğunda, bir modüle yol eklemek gerekmez, otomatik olarak eklenir.

Örnek:

İçinde script.pyve var olan bir klasörüm varsa module.py, modülü basitçe içe aktarabilirim:

import module

Ayrıca python.org/dev/peps/pep-0328 , özellikle Python 3'ü hedefliyorsanız (veya gelecekte hedeflemeyi planlıyorsanız)
zaadeh

Neden printenv PYTHONPATHhiçbir şey
Stevie G

1
sys.path.append("/path/to/your/package_or_module")ayrıca varsayılana bir yol ekler ve daha az kafa karıştırıcıdır. İlk tartışmanın sys.path.insert(0,...)hangisi olduğu ile karşılaştırıldığında 0.
Paul Rougieux

1
@PaulRougieux: Yola ekleme ile ilgili sorun, modülünüzün yolun başka bir yerinde (örneğin bir .egg dosyasında) bulunabileceği ve dosyanızdaki sürüm yerine modülünüzün bu sürümünü alacağınızdır .
10'da

6

Göreceli içe aktarmayı kullanmanın doğru yolu şudur:

from ..Common import foo1

Ayrıca __init__.pytüm klasörlerinize de ihtiyacınız var .


1
Teşekkür. Fakat iki klasörden oluşan bir modülüm varsa Yukarıya nasıl aktarırım? from .... Klasör çalışmıyor
user284474

Tek seviyede çalışıyor mu?
Sylvain Pineau

Tek bir seviye ile çalışır.
user284474

tamam, lütfen bu cevabı kabul eder misiniz? çok düzeyli için farklı bir soru gelebilir gerçi ama önce bu bir göz atın sorusuna ve bu cevabı bir ambalajın içinde bulunan modülleri çağırmak için en iyi yol
Sylvain Pineau

Bu Python 2 veya Python 3 için doğru mu? Ya da her ikisi de?
alex,

2

Not: Bu cevap python 3'ün en son versiyonu için eski, fakat daha önceki versiyon için burada. Daha fazla bilgi için yorumları okuyun ve https://www.python.org/dev/peps/pep-0420/


Temelde , sistem yoluna eklemek istediğiniz python kodlu her klasörün bir __init__.py dosyasına ihtiyacı vardır. Bu __init__.py dosyaları boş olabilir.


Anladığım kadarıyla, artık durum böyle değil, dizin artık bir "ad alanı" oluyor.
Aaron Hall

@AaronHall ilginç, kaynak?
don.joey

1
Bunu kanıt olarak deneyin: python -c "from pathlib import Path; Path('ns').mkdir(); Path('ns/mod.py').write_text('''print('mod.py')'''); import ns.mod; from shutil import rmtree; rmtree('ns')"ayrıca , ad alanı paketi anlambiliminin eklenmesini açıklayan PEP 420 ile
Aaron Hall,
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.