6. Modüller¶
Python yorumlayıcısından çıkıp tekrar girerseniz, yaptığınız tanımlar (fonksiyonlar ve değişkenler) kaybolur. Bu nedenle, daha uzun bir program yazmak istiyorsanız, girdiyi yorumlayıcıya hazırlarken bir metin düzenleyicisi kullanmak ve o dosyayla girdi olarak çalıştırmak daha iyidir. Bu bir script oluşturma olarak bilinir. Programınız uzadıkça, daha kolay bakım için birkaç dosyaya bölmek isteyebilirsiniz. Ayrıca, tanımını her programa kopyalamadan, birkaç programda yazdığınız kullanışlı bir fonksiyonu kullanmak isteyebilirsiniz.
Bunu desteklemek için Python, tanımları bir dosyaya koymanın ve bunları bir komut dosyasında veya yorumlayıcının etkileşimli bir örneğinde kullanmanın bir yolunu sağlar. Böyle bir dosyaya module denir; bir modülden alınan tanımlar diğer modüllere veya main modülüne (en üst düzeyde ve hesap makinesi modunda yürütülen bir komut dosyasında erişiminiz olan değişkenlerin derlenmesi) aktarılabilir.
Modül, Python tanımlarını ve ifadelerini içeren bir dosyadır. Dosya adı, .py
son ekini içeren modül adıdır. Bir modül içinde, modülün adı (dize olarak) __name__
genel değişkeninin değeri olarak kullanılabilir. Örneğin, geçerli dizinde aşağıdaki içeriklerle fibo.py
adlı bir dosya oluşturmak için en sevdiğiniz metin düzenleyicisini kullanın:
# Fibonacci numbers module
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
def fib2(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
Şimdi Python yorumlayıcısına girin ve bu modülü aşağıdaki komutla içe aktarın:
>>> import fibo
Bu, fibo
‘da tanımlanan işlevlerin adlarını doğrudan geçerli namespace ‘e eklemez (daha fazla ayrıntı için bkz. Python Etki Alanları ve Ad Alanları); oraya sadece fibo
modül adını ekler. Modül adını kullanarak şu işlevlere erişebilirsiniz:
>>> fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'
Bir işlevi sık sık kullanmayı düşünüyorsanız, işlevi yerel bir ada atayabilirsiniz:
>>> fib = fibo.fib
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
6.1. Modüller hakkında daha fazla¶
Bir modül, işlev tanımlarının yanı sıra çalıştırılabilir ifadeler de içerebilir. Bu ifadeler modülü başlatmayı amaçlamaktadır. Yalnızca bir import ifadesinde modül adıyla karşılaşıldığında ilk kez yürütülürler. [1] (Dosya komut dosyası olarak yürütülürse de çalıştırılırlar.)
Her modülün, modülde tanımlanan tüm işlevler tarafından genel ad alanı olarak kullanılan kendi özel ad alanı vardır. Böylece, bir modülün yazarı, bir kullanıcının genel değişkenleriyle yanlışlıkla çakışma endişesi duymadan, modüldeki genel değişkenleri kullanabilir. Öte yandan, ne yaptığınızı biliyorsanız, bir modülün global değişkenlerine, işlevlerine atıfta bulunmak için kullanılan modname.itemname
notasyonuyla dokunabilirsiniz.
Modüller diğer modülleri içe aktarabilir. Tüm import
ifadelerinin bir modülün (veya bu konuda betiğin) başına yerleştirilmesi alışılmış bir durumdur ancak gerekli değildir. İçe aktarılan modül adları, bir modülün en üst düzeyine yerleştirilirse (herhangi bir işlev veya sınıfın dışında), modülün genel ad alanına eklenir.
import
ifadesinin, bir modülden adları doğrudan içe aktaran modülün ad alanına aktaran bir çeşidi vardır. Örneğin:
>>> from fibo import fib, fib2
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Bu, içe aktarmaların yerel ad alanında alındığı modül adını tanıtmaz(bu nedenle örnekte fibo
tanımlanmamıştır).
Bir modülün tanımladığı tüm adları içe aktarmak için bir varyant bile vardır:
>>> from fibo import *
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Bu, alt çizgiyle başlayanlar (_
) dışındaki tüm isimleri alır. Çoğu durumda Python programcıları bu özelliği kullanmaz, çünkü yorumlayıcıya bilinmeyen bir ad kümesi ekler ve muhtemelen önceden tanımladığınız bazı şeyleri gizler.
Genel olarak, bir modülden veya paketten *
içeri aktarma uygulamasının, genellikle okunamayan koda neden olduğundan hoş karşılanmadığına dikkat edin. Ancak, etkileşimli oturumlarda yazmayı kaydetmek için kullanmak sorun değildir.
Modül adının ardından as
geliyorsa, as
‘den sonraki ad doğrudan içe aktarılan modüle bağlanır.
>>> import fibo as fib
>>> fib.fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Bu, modülün import fibo
‘nun yapacağı şekilde etkin bir şekilde içe aktarılmasıdır, tek farkı fib
olarak mevcut olmasıdır.
Benzer efektlere sahip from
kullanılırken de kullanılabilir:
>>> from fibo import fib as fibonacci
>>> fibonacci(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377
Not
Verimlilik nedeniyle, her modül yorumlayıcı oturumu başına yalnızca bir kez içe aktarılır. Bu nedenle, modüllerinizi değiştirirseniz, yorumlayıcıyı yeniden başlatmanız gerekir - veya etkileşimli olarak test etmek istediğiniz tek bir modülse, importlib.reload()
, örneğin importlib; importlib.reload(modulename)
.
6.1.1. Modülleri komut dosyası olarak yürütme¶
Bir Python modülünü :: ile çalıştırdığınızda:
python fibo.py <arguments>
modüldeki kod, içe aktardığınız gibi yürütülür, ancak __name__
"__main__"
olarak ayarlanır. Bu, modülünüzün sonuna bu kodu ekleyerek:
if __name__ == "__main__":
import sys
fib(int(sys.argv[1]))
dosyayı bir komut dosyası ve içe aktarılabilir bir modül olarak kullanılabilir hale getirebilirsiniz, çünkü komut satırını ayrıştıran kod yalnızca modül “main” dosya olarak yürütülürse çalışır:
$ python fibo.py 50
0 1 1 2 3 5 8 13 21 34
Modül içe aktarılırsa kod çalıştırılmaz:
>>> import fibo
>>>
Bu genellikle bir modüle uygun bir kullanıcı arabirimi sağlamak veya test amacıyla kullanılır (modülü komut dosyası olarak çalıştırmak bir test paketi yürütür).
6.1.2. Modül Arama Yolu¶
spam
adında bir modül içe aktarıldığında, yorumlayıcı ilk olarak bu ada sahip gömülü bir modül arar. Bu modül adları sys.builtin_module_names
içinde listelenir. Bulamazsa, sys.path
değişkeni tarafından verilen dizin listesinde spam.py
adlı bir dosya arar. sys.path
bu konumlardan başlatılır:
Girdi komut dosyasını içeren dizin (veya dosya belirtilmediğinde geçerli dizin).
PYTHONPATH
(kabuk değişkeniPATH
ile aynı sözdizimine sahip dizin adlarının listesi).Kuruluma bağlı varsayılan (kural olarak,
site
modülü tarafından işlenen bir “site-packages” dizini dahil).
Daha fazla ayrıntı The initialization of the sys.path module search path adresindedir.
Not
Symlink’leri destekleyen dosya sistemlerinde, symlink izlendikten sonra girdi komut dosyasını içeren dizin hesaplanır. Başka bir deyişle, symlink içeren dizin modül arama yoluna not eklenir.
Başlatıldıktan sonra Python programları sys.path
değiştirebilir. Çalıştırılmakta olan komut dosyasını içeren dizin, arama yolunun başına, standart kitaplık yolunun önüne yerleştirilir. Bu, kitaplık dizininde aynı ada sahip modüller yerine bu dizindeki komut dosyalarının yüklanacağı anlamına gelir. Değiştirme amaçlanmadığı sürece bu bir hatadır. Daha fazla bilgi için Standart modüller bölümüne bakın.
6.1.3. “Derlenmiş” Python dosyaları¶
Modüllerin yüklenmesini hızlandırmak için Python, her modülün derlenmiş sürümünü __pycache__
dizininde module.version.pyc
adı altında önbelleğe alır; burada sürüm, derlenen dosyanın biçimini kodlar; genellikle Python sürüm numarasını içerir. Örneğin, CPython 3.3 sürümünde spam.py’nin derlenmiş sürümü __pycache__/spam.cpython-33.pyc
olarak önbelleğe alınacaktır. Bu adlandırma kuralı, farklı sürümlerden ve Python’un farklı sürümlerinden derlenmiş modüllerin bir arada var olmasına izin verir.
Python, eski olup olmadığını ve yeniden derlenmesi gerekip gerekmediğini görmek için kaynağın değişiklik tarihini derlenmiş sürümle karşılaştırır. Bu tamamen otomatik bir işlemdir. Ayrıca, derlenen modüller platformdan bağımsızdır, bu nedenle aynı kitaplık farklı mimarilere sahip sistemler arasında paylaşılabilir.
Python iki durumda önbelleği kontrol etmez. İlk olarak, doğrudan komut satırından yüklenen modülün sonucunu her zaman yeniden derler ve saklamaz. İkincisi, kaynak modül yoksa önbelleği kontrol etmez. Kaynak olmayan (yalnızca derlenmiş) bir dağıtımı desteklemek için, derlenen modül kaynak dizinde olmalı ve bir kaynak modül olmamalıdır.
Uzmanlar için bazı ipuçları:
Derlenmiş bir modülün boyutunu küçültmek için Python komutundaki
-O
veya-OO
anahtarlarını kullanabilirsiniz.-O
anahtarı, onaylama ifadelerini kaldırır,-OO
anahtarı, hem assert ifadelerini hem de __doc__ dizelerini kaldırır. Bazı programlar bunların kullanılabilir olmasına güvenebileceğinden, bu seçeneği yalnızca ne yaptığınızı biliyorsanız kullanmalısınız. “Optimize edilmiş” modüller bir “opt-” etiketine sahiptir ve genellikle daha küçüktür. Gelecekteki sürümler, optimizasyonun etkilerini değiştirebilir.Bir program
.pyc
dosyasından okunduğunda,.py
dosyasından okunduğundan daha hızlı çalışmaz;.pyc
dosyaları hakkında daha hızlı olan tek şey, yüklenme hızlarıdır.compileall
modülü, bir dizindeki tüm modüller için .pyc dosyaları oluşturabilir.PEP 3147 ‘de, kararların bir akış şeması da dahil olmak üzere, bu süreç hakkında daha fazla ayrıntı bulunmaktadır.
6.2. Standart modüller¶
Python, ayrı bir belge olan Python Kütüphane Referansında (buradan itibaren “Kütüphane Referansı”) açıklanan standart modüllerden oluşan bir kütüphaneyle birlikte gelir. Bazı modüller yorumlayıcıda yerleşik olarak bulunur; bunlar dilin çekirdeğinin bir parçası olmayan ancak yine de verimlilik için veya sistem çağrıları gibi işletim sistemi ilkellerine erişim sağlamak için yerleşik olarak bulunan işlemlere erişim sağlar. Bu tür modüllerin kümesi, altta yatan platforma da bağlı olan bir yapılandırma seçeneğidir. Örneğin, winreg
modülü yalnızca Windows sistemlerinde sağlanır. Belirli bir modül biraz ilgiyi hak ediyor: sys
, her Python yorumlayıcısında yerleşik olarak bulunur. sys.ps1
ve sys.ps2
değişkenleri birincil ve ikincil istemler olarak kullanılan dizeleri tanımlar:
>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Yuck!')
Yuck!
C>
Bu iki değişken yalnızca yorumlayıcı etkileşimli moddaysa tanımlanır.
sys.path
değişkeni, yorumlayıcının modüller için arama yolunu belirleyen bir dizeler listesidir. PYTHONPATH
ortam değişkeninden veya PYTHONPATH
ayarlanmamışsa yerleşik bir varsayılan değerden alınan varsayılan bir yola başlatılır. Standart liste işlemlerini kullanarak değiştirebilirsiniz:
>>> import sys
>>> sys.path.append('/ufs/guido/lib/python')
6.3. dir()
Fonksiyonu¶
Yerleşik fonksiyon dir()
, bir modülün hangi adları tanımladığını bulmak için kullanılır. Sıralanmış bir dize listesi döndürür:
>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)
['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__',
'__interactivehook__', '__loader__', '__name__', '__package__', '__spec__',
'__stderr__', '__stdin__', '__stdout__', '__unraisablehook__',
'_clear_type_cache', '_current_frames', '_debugmallocstats', '_framework',
'_getframe', '_git', '_home', '_xoptions', 'abiflags', 'addaudithook',
'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix',
'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing',
'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info',
'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info',
'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth',
'getallocatedblocks', 'getdefaultencoding', 'getdlopenflags',
'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile',
'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval',
'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
'intern', 'is_finalizing', 'last_traceback', 'last_type', 'last_value',
'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks',
'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'pycache_prefix',
'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth', 'setdlopenflags',
'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr',
'stdin', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info',
'warnoptions']
Argümanlar olmadan, dir()
, şu anda tanımladığınız adları listeler:
>>> a = [1, 2, 3, 4, 5]
>>> import fibo
>>> fib = fibo.fib
>>> dir()
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
Her tür adın listelendiğini unutmayın: değişkenler, modüller, fonksiyonlar vb.
dir()
yerleşik fonksiyonlarun ve değişkenlerin adlarını listelemez. Bunların bir listesini istiyorsanız, standart modül builtins
‘de tanımlanırlar:
>>> import builtins
>>> dir(builtins)
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',
'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning',
'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError',
'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',
'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
'FileExistsError', 'FileNotFoundError', 'FloatingPointError',
'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError',
'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError',
'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError',
'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented',
'NotImplementedError', 'OSError', 'OverflowError',
'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError',
'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',
'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',
'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',
'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__',
'__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs',
'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable',
'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits',
'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit',
'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr',
'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass',
'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview',
'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property',
'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice',
'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars',
'zip']
6.4. Paketler¶
Paketler, Python’un modül isim alanını “noktalı modül isimleri” kullanarak yapılandırmanın bir yoludur. Örneğin, A.B
modül adı, A
adlı bir paketteki B
adlı bir alt modülü belirtir. Modül kullanımının farklı modüllerin yazarlarını birbirlerinin global değişken isimleri hakkında endişelenmekten kurtarması gibi, noktalı modül isimlerinin kullanımı da NumPy veya Pillow gibi çok modüllü paketlerin yazarlarını birbirlerinin modül isimleri hakkında endişelenmekten kurtarır.
Ses dosyalarının ve ses verilerinin tek tip işlenmesi için bir modül koleksiyonu (“paket”) tasarlamak istediğinizi varsayalım. Birçok farklı ses dosyası biçimi vardır (genellikle uzantılarıyla tanınır, örneğin: .wav
, .aiff
, .au
) bu nedenle, çeşitli dosya biçimleri arasında dönüşüm için büyüyen bir modül koleksiyonu oluşturmanız ve sürdürmeniz gerekebilir. Ses verileri üzerinde gerçekleştirmek isteyebileceğiniz birçok farklı işlem de vardır (karıştırma, eko ekleme, ekolayzır işlevi uygulama, yapay bir stereo efekti oluşturma gibi) bu nedenle ek olarak, bu işlemleri gerçekleştirmek için hiç bitmeyen bir modül akışı yazıyor olacaksınız. İşte paketiniz için olası bir yapı (hiyerarşik bir dosya sistemi cinsinden ifade edilir):
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
Paketi içe aktarırken Python, paket alt dizinini arayan sys.path
üzerindeki dizinleri arar.
__init__.py
dosyaları, Python’un dosyayı içeren dizinleri paket olarak ele almasını sağlamak için gereklidir (nispeten gelişmiş bir özellik olan namespace package kullanılmadığı sürece). Bu, string
gibi ortak bir ada sahip dizinlerin, modül arama yolunda daha sonra ortaya çıkan geçerli modülleri istemeden gizlemesini önler. En basit durumda, __init__.py
sadece boş bir dosya olabilir, ancak aynı zamanda paket için başlatma kodunu çalıştırabilir veya daha sonra açıklanacak olan __all__
değişkenini ayarlayabilir.
Paketin kullanıcıları, paketin içindeki ayrı modülleri içe aktarabilir, örneğin:
import sound.effects.echo
Bu, sound.effects.echo
alt modülünü yükler. Tam adı ile referans verilmelidir.
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
Alt modülü içe aktarmanın alternatif bir yolu:
from sound.effects import echo
Bu aynı zamanda echo
alt modülünü yükler ve paket öneki olmadan kullanılabilir hale getirir, böylece aşağıdaki gibi kullanılabilir:
echo.echofilter(input, output, delay=0.7, atten=4)
Yine başka bir varyasyon, istenen işlevi veya değişkeni doğrudan içe aktarmaktır:
from sound.effects.echo import echofilter
Yine, bu, echo
alt modülünü yükler, ancak bu, echofilter()
fonksiyonunu doğrudan kullanılabilir hale getirir:
echofilter(input, output, delay=0.7, atten=4)
from package import item
kullanırken, öğenin paketin bir alt modülü (veya alt paketi) veya pakette tanımlanmış bir fonksiyon, sınıf veya değişken gibi başka bir ad olabileceğini unutmayın. import
ifadesi önce öğenin pakette tanımlanıp tanımlanmadığını test eder; değilse modül olduğunu varsayar ve yüklemeye çalışır. Onu bulamazsa, bir ImportError
istisnası ortaya çıkar.
Aksine, import item.subitem.subsubitem
gibi bir sözdizimi kullanırken, sonuncusu hariç her öğe bir paket olmalıdır; son öğe bir modül veya paket olabilir, ancak önceki öğede tanımlanan bir sınıf, fonksiyon veya değişken olamaz.
6.4.1. Bir Paketten * İçe Aktarma¶
Şimdi, kullanıcı from sound.effects import *
yazdığında ne olur? İdeal olarak, bunun bir şekilde dosya sistemine gitmesi, pakette hangi alt modüllerin bulunduğunu bulması ve hepsini içe aktarması umulur. Bu uzun zaman alabilir ve alt modüllerin içe aktarılması, yalnızca alt modül açıkça içe aktarıldığında gerçekleşmesi gereken istenmeyen yan etkilere neden olabilir.
Tek çözüm, paket yazarının paketin açık bir dizinini sağlamasıdır. import
ifadesi aşağıdaki kuralı kullanır: eğer bir paketin __init__.py
kodu __all__
adlı bir liste tanımlarsa, from package import *
ile karşılaşıldığında alınması gereken modül adlarının listesi olarak alınır. Paketin yeni bir sürümü yayınlandığında bu listeyi güncel tutmak paket yazarının sorumluluğundadır. Paket yazarları, paketlerinden * içe aktarmak için bir kullanım görmezlerse, onu desteklememeye de karar verebilirler. Örneğin, sound/effects/__init__.py
dosyası şu kodu içerebilir:
__all__ = ["echo", "surround", "reverse"]
Bu, from sound.effects import *
ifadesinin sound.effects
paketinin üç adlandırılmış alt modülünü içe aktaracağı anlamına gelir.
Alt modüllerin yerel olarak tanımlanmış isimler tarafından gölgelenebileceğini unutmayın. Örneğin, sound/effects/__init__.py
dosyasına bir reverse
fonksiyonu eklediyseniz, from sound.effects import *
sadece iki alt modül olan echo
ve surround``u içe aktarır, ancak *reverse
alt modülünü içe aktarmaz, çünkü yerel olarak tanımlanmış reverse
fonksiyonu tarafından gölgelenir:
__all__ = [
"echo", # refers to the 'echo.py' file
"surround", # refers to the 'surround.py' file
"reverse", # !!! refers to the 'reverse' function now !!!
]
def reverse(msg: str): # <-- this name shadows the 'reverse.py' submodule
return msg[::-1] # in the case of a 'from sound.effects import *'
Eğer __all__
tanımlanmamışsa, from sound.effects import *
ifadesi sound.effects
paketindeki tüm alt modülleri geçerli isim alanına import etmez; sadece sound.effects
paketinin import edildiğinden emin olur (muhtemelen __init__.py
içindeki herhangi bir başlatma kodunu çalıştırır) ve sonra pakette tanımlanan isimleri import eder. Bu, __init__.py
tarafından tanımlanan (ve alt modülleri açıkça yüklenen) tüm isimleri içerir. Ayrıca, önceki import
deyimleri tarafından açıkça yüklenmiş olan paketin tüm alt modüllerini de içerir. Bu kodu göz önünde bulundurun:
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
Bu örnekte, echo
ve surround
modülleri, from...import
deyimi çalıştırıldığında sound.effects
paketinde tanımlandıkları için geçerli ad alanında içe aktarılır. (Bu aynı zamanda __all__
tanımlandığında da çalışır).
Bazı modüller, import *
kullandığınızda yalnızca belirli kalıpları takip eden adları dışa aktarmak üzere tasarlanmış olsa da, üretim kodunda yine de kötü uygulama olarak kabul edilir.
Unutmayın, from package import specific_submodule
kullanmanın yanlış bir tarafı yok! Aslında, içe aktarma modülünün farklı paketlerden aynı ada sahip alt modülleri kullanması gerekmedikçe, önerilen gösterim budur.
6.4.2. Paket İçi Referanslar¶
Paketler alt paketler halinde yapılandırıldığında (örnekteki sound
paketinde olduğu gibi), kardeş paketlerin alt modüllerine başvurmak için mutlak içe aktarımları kullanabilirsiniz. Örneğin, sound.filters.vocoder
modülünün sound.effects
paketindeki echo
modülünü kullanması gerekiyorsa, from sound.effects import echo
kullanabilir.
Ayrıca, içe aktarma ifadesinin from module import name
formuyla göreli içe aktarmaları(relative import) da yazabilirsiniz. Bu içe aktarmalar, göreli içe aktarmada(relative import) yer alan mevcut ve ana paketleri belirtmek için baştaki noktaları kullanır. Örneğin surround
modülünden şunları kullanabilirsiniz:
from . import echo
from .. import formats
from ..filters import equalizer
Göreceli içe aktarmaların 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üller her zaman mutlak içe aktarma kullanmalıdır.
6.4.3. Birden Çok Dizindeki Paketler¶
Packages support one more special attribute, __path__
. This is
initialized to be a sequence of strings containing the name of the
directory holding the
package’s __init__.py
before the code in that file is executed. This
variable can be modified; doing so affects future searches for modules and
subpackages contained in the package.
Bu özelliğe sıklıkla ihtiyaç duyulmasa da, bir pakette bulunan modül dizisini genişletmek için kullanılabilir.
Dipnotlar