Python modülü ile Python paketi arasındaki fark nedir?


576

Python modülü ile Python paketi arasındaki fark nedir?

Ayrıca bkz: "paket" ve "modül" arasındaki fark nedir (diğer diller için)


9
Yanılıyor olabilirim ama benim için: bir modül temelde bir python dosyası. Paket, bir grup modül içeren bir klasördür (python dosyaları).
lc2817

36
Bir paket olarak değerlendirilmek için, bu klasör bir __init__.pydosya içermelidir .
Giulio Piancastelli

@ lc2817: bu en yaygın durumdur, ancak bir modülün bir dosya sisteminden yüklenmesi gerekmez; örneğin, uygulamaya bakınfrom plumbum.cmd import ls
jfs

4
@GiulioPiancastelli: Python 3.3+ sürümünde ad alanı paketleri kullanılmaz__init__.py
jfs

Topluluk, Python paketleri ile PyPI / wheels / etc gibi Python bileşenlerini dağıtmak için kullanılan paketler arasında nasıl bir ayrım yapar? İkisi bana "paket" kelimesinin farklı uygulamaları gibi geliyor.
davidA

Yanıtlar:


373

Modül, tek bir içe aktarma altında içe aktarılan ve kullanılan tek bir dosyadır (veya dosyalar). Örneğin

import my_module

Paket, dizinlerde bir paket hiyerarşisi veren modüllerden oluşan bir koleksiyondur.

from my_package.timing.danger.internets import function_of_love

Modüller için belgeler

Paketlere giriş


54
"Bir modül, bir içe aktarma altında içe aktarılan tek bir dosyadır (veya dosyalar)" derken, bir modülün birden fazla dosya olduğu durumu açıklayabilir misiniz? Yoksa ne demek istediğini yanlış mı söylüyorum?
Kullanıcı 11

5
Bir modül oluşturmak için bir dosyaya ihtiyacınız yoktur, örneğin bir modülü zip dosyasından içe aktarabilirsiniz. Aynı paketler için. Python'da modüller / paketler için sadece bir sınıf vardır. Paket sadece __path__niteliği olan bir modüldür .
jfs

33
Paketler de modüllerdir . Sadece farklı şekilde paketlenirler; bunlar bir dizin artı __init__.pydosya kombinasyonu tarafından oluşturulur . Diğer modülleri içerebilen modüllerdir.
Martijn Pieters

15
@ Emin olun, bkz . Referans belgelerindeki içe aktarma sistemi : Tüm paketlerin modül olduğunu unutmayın .
Martijn Pieters

6
@Jacquot: ve bir “paket” ile sözlüğü : alt modülü veya ters, alt paketlerin içerebilen Pithon. Teknik olarak, bir paket __path__özniteliği olan bir Python modülüdür .
Martijn Pieters

556

Herhangi bir Python dosyası bir modüldür , adı dosyanın .pyuzantısı olmadan temel adıdır . Bir paket Python modülleri bir koleksiyon: Bir modül tek Python dosya ise, bir paket ek içeren Python modülleri bir dizindir __init__.pysadece Python komut bir demet barındırıyorsa bu bir dizinden bir paket ayırt etmek, dosyayı. Karşılık gelen dizinlerin kendilerine ait olması koşuluyla paketler herhangi bir derinliğe yerleştirilebilir__init__.py dosyalarını .

Modül ve paket arasındaki farkın sadece dosya sistemi düzeyinde olduğu görülüyor. Bir modülü veya paketi içe aktardığınızda, Python tarafından oluşturulan karşılık gelen nesne her zaman türdedir module. Ancak, bir paketi içe __init__.pyaktardığınızda , yalnızca o paketin dosyasındaki değişkenler / işlevler / sınıfların alt paketler veya modüller tarafından doğrudan görünmediğini unutmayın . Örnek olarak, xmlPython standart kitaplığındaki paketi düşünün : xmldizini bir __init__.pydosya ve dört alt dizin içerir ; alt dizin etreebir __init__.pydosya ve diğerleri arasında bir ElementTree.pydosya içerir. Paketi / modülleri etkileşimli olarak içe aktarmaya çalıştığınızda ne olacağını görün:

>>> import xml
>>> type(xml)
<type 'module'>
>>> xml.etree.ElementTree
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'etree'
>>> import xml.etree
>>> type(xml.etree)
<type 'module'>
>>> xml.etree.ElementTree
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'ElementTree'
>>> import xml.etree.ElementTree
>>> type(xml.etree.ElementTree)
<type 'module'>
>>> xml.etree.ElementTree.parse
<function parse at 0x00B135B0>

Python'da sys, C ile yazılmış gibi yerleşik modüller de var , ancak sorunuzdaki bunları düşünmek istediğinizi düşünmüyorum.


9
Python tarafından oluşturulan karşılık gelen nesnenin her zaman türünde olduğunu açıkça belirttiğiniz için teşekkür ederiz module. Bir hata ayıklayıcı yazma sürecindeyim ve hata ayıklayıcının paketlerimin modules olduğunu söylerken yanlış olduğundan endişeliydim .
ArtOfWarfare

8
@jolvi Çizgi adı içeren bir dosya adına sahip Python dosyaları, her zamanki importifadeyle değil, yine de modül olarak içe aktarılabilir , çünkü Python tanımlayıcılarında tirelara izin verilmez. importlib.import_module()Bunun yerine kullanın .
Giulio Piancastelli

2
@jolvi Değilim. Yorumumun neresinde okuyorsun? Sadece söylüyorum, eğer kendi adında tire bulunan bir Python dosyasına sahipseniz veya rastlarsanız, yine de bir modül olarak içe aktarabilirsiniz. Python dosyasını adlandırmanın tercih edilen yolu hakkında bir açıklama yapmıyorum. Eminim bunu başka bir yerde bulabilirsiniz: alt çizgi lehine tire kullanmaktan kaçınılması şiddetle tavsiye edilir.
Giulio Piancastelli

3
Üst paketi alırken varsayılan olarak Python, alt paketler veya modüller için kullanılamam yeni olmak beni tökezletti. Bunun özel bir nedeni var mı? Üst paketi içe aktarırken alt paketlerin veya modüllerin (tam adlarıyla) nasıl kullanılabilir hale getirileceğine dair ortak bir model var mı?
sschuberth

2
@sschuberth Üst paketleri sadece bir üst paketin init .py dosyasına içe aktarın .
Anna

33

Gönderen Python sözlüğü :

Tüm paketlerin modül olduğunu, ancak tüm modüllerin paket olmadığını unutmayın. Ya da başka bir deyişle, paketler sadece özel bir modül türüdür. Özellikle, __path__öznitelik içeren herhangi bir modül bir paket olarak kabul edilir.

Adında tire işareti olan Python dosyaları, my-file.pybasit bir deyimle içe aktarılamaz import. Kod import my-fileolarak import my - file, bir istisna yaratacak olanla aynıdır . Bu tür dosyalar komut dosyaları olarak daha iyi karakterize edilirken, içe aktarılabilir dosyalar modüllerdir .


23

İlk olarak, bir modülün , kesin tanımıyla , genellikle bir veya daha fazla dosyayı diskten okuyarak oluşturulan bir Python yorumlayıcısının belleğindeki bir nesne olduğunu unutmayın . Gayri resmi olarak a/b/c.py"modül" gibi bir disk dosyasını çağırabilsek de sys.path, modül nesnesini oluşturmak için diğer bazı kaynaklardan (örneğin ) gelen bilgilerle birleştirilene kadar aslında bir dosya haline gelmez .

(Örneğin, diğer adlara sys.pathve diğer ayarlara bağlı olarak farklı adlara sahip iki modülün aynı dosyadan yüklenebileceğini unutmayın. Bu tam olarak yorumlayıcıda python -m my.modulebir ile olur import my.module; iki modül nesnesi olacak __main__ve my.moduleher ikisi de oluşturulacak diskteki aynı dosyadan my/module.py.)

Bir paket (alt paket dahil) alt modülü sahip olabilen bir modüldür. Tüm modüller bunu yapamaz. Örnek olarak, küçük bir modül hiyerarşisi oluşturun:

$ mkdir -p a/b
$ touch a/b/c.py

Altında başka dosya olmadığından emin olun a. Bir Python 3.4 veya üstü yorumlayıcı (örn. python3 -iİle) başlatın ve aşağıdaki ifadelerin sonuçlarını inceleyin:

import a
a                 <module 'a' (namespace)>
a.b               AttributeError: module 'a' has no attribute 'b'
import a.b.c
a.b               <module 'a.b' (namespace)>
a.b.c             <module 'a.b.c' from '/home/cjs/a/b/c.py'>

Modüller ave a.bpaketler (aslında, "ad alanı paketi" olarak adlandırılan belirli bir paket, ancak burada bunun için endişelenmeyiz). Ancak, modül a.b.cbir paket değildir. a/b.pyYukarıdaki dizin yapısına başka bir dosya ekleyerek ve yeni bir yorumlayıcı başlatarak bunu gösterebiliriz :

import a.b.c
 ImportError: No module named 'a.b.c'; 'a.b' is not a package
import a.b
a                 <module 'a' (namespace)>
a.__path__        _NamespacePath(['/.../a'])
a.b               <module 'a.b' from '/home/cjs/tmp/a/b.py'>
a.b.__path__      AttributeError: 'module' object has no attribute '__path__'

Python, bir alt modül yüklenmeden önce tüm üst modüllerin yüklenmesini sağlar. Yukarıda a/bir dizin olduğunu bulur ve böylece bir ad alanı paketi oluşturur ave bu a/b.py, yüklediği ve (paket olmayan) bir modül oluşturmak için kullandığı bir Python kaynak dosyasıdır a.b. Bu noktada bir modülünüz olamaz a.b.cçünküa.b submodules olamaz böylece bir paket değildir ve.

Burada ayrıca paket modülünün abir __path__niteliği olduğunu (paketlerin buna sahip olması gerekir), ancak paket dışı modülün a.bolmadığını görebilirsiniz.


1
Henüz yapmadıysanız, geri dönün ve bu yanıttaki örnekleri inceleyin.
Donal Lafferty

2

Geç cevap, başka bir tanım:

Bir paket, bağımsız bir modül olabilen ithal edilmiş bir üst varlık veya __init__.pybir alt dizin yapısı içindeki bir modül grubundan üst öğe olarak özel modül ile temsil edilir.

Yani fiziksel olarak bir paket, bir veya daha fazla modül sağlayan bir dağıtım birimidir.


1
Python'da paket için iki tanım olduğunu ve farklı olduklarını hissediyorum . Cevabınız onları birleştiriyor gibi görünüyor. Açıkçası, bir python paketi __init__.pyiçinde modül bulunan bir dizindir , ancak dağıtım birimleri hakkında konuşursanız (genellikle PyPI aracılığıyla), bu tamamen başka bir paket türüdür (genellikle varlığı ile tanımlanır setup.py). packageKafa karıştırıcı terimin bu iki kullanımını buluyorum ve onu tamamen şaşkınlık içinde bulan bazı Python yeni başlayanlarla konuştum.
DavidA

@davidA, Sadece nasıl hissettiğiniz değil. Bu kodlanmış oldu: packaging.python.org/glossary/#term-distribution-package (Teşekkür de netleştirilmesi için!)
Lorem Ipsum

0

Paket aynı zamanda diğer modülleri, 'basit dosya tabanlı modülleri ve paketleri (alt paket)' içerebilen bir modüldür. Modülün paket tipiyle ilgili kod __init__.pydosyaya girer .

import pack1
print(type(pack1))

modüller, bir modülü içe aktardıktan sonra, modülde tanımlanan tanımlayıcılara erişebileceğiniz bir nesne gibi davranan, fonksiyonlar, sınıflar, çalıştırılabilir kod vb. içeren basit bir dosyadır.

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.