2.19. Modül yazma

Herhangi bir .py dosyası bir modüldür. Büyüyen bir betiği birkaç dosyaya bölmek her dosyayı kısa tutar ve ortak yardımcıların betikler arasında paylaşılmasını sağlar.

2.19.1. Bir betiği bölme

İlgili bir fonksiyon grubunu kendi dosyalarına çekin:

camera_utils.py

def banner():
    print("OpenMV")

def label(text):
    return "[" + text + "]"

main.py

import camera_utils

camera_utils.banner()
print(camera_utils.label("ready"))

Çıktı:

OpenMV
[ready]

İki dosya aynı dizinde yan yana durur. main.py çalıştığında, import camera_utils, camera_utils.py dosyasını bir kez okur, üst düzey ifadelerini çalıştırır ve elde edilen modül nesnesini main içindeki camera_utils adına bağlar. Başka herhangi bir yerden gelen ikinci bir import camera_utils aynı nesneyi döndürür – modüller ilk yüklemelerinden sonra önbelleğe alınır.

Bir modülün adı dosya adından gelir, bu nedenle camera_utils.py, import camera_utils olarak içe aktarılır.

2.19.2. Çok dosyalı modüller (paketler)

Bir modül, tek bir .py yerine bir dosya dizini de olabilir. Dizinin adı modül adı olur ve içindeki dosyalar onun alt modülleridir:

camera_utils/
    __init__.py
    text.py
    timing.py

__init__.py, paketin kendisi içe aktarıldığında çalışan dosyadır; boş olabilir ya da alt modüllerden seçili isimleri yeniden dışa aktarabilir. Alt modüllere noktalı bir adla erişilir:

import camera_utils.text
from camera_utils.timing import elapsed

camera_utils.text.label("ready")

Paketin içinde, alt modüller birbirlerine ya tam noktalı adla ya da “bu paket” anlamına gelen baştaki bir nokta kullanan bir göreceli içe aktarma ile erişebilir:

camera_utils/timing.py

from . import text             # the sibling submodule

def stamp(value):
    return text.label(str(value))

Bunun yerine belirli bir ismi getirmek için, onu noktalı kardeşten sonra adlandırın:

from .text import label

def stamp(value):
    return label(str(value))

Göreceli içe aktarmalar bir paketi kendi içinde tutar: paket dizinini yeniden adlandırmak her alt modülü düzenlemeyi gerektirmez.

Tek bir dosya rahat bir boyutu aştığında veya ilgili bir modül kümesi tek bir ad alanı altında birlikte bulunduğunda bir paket kullanın. Günlük betikler için tek bir .py dosyası yeterlidir.

2.19.3. __name__ koruması

Her modülün yerleşik bir __name__ adı vardır. Değeri, dosyanın nasıl kullanıldığına bağlıdır:

  • Dosya doğrudan çalıştırıldığında, __name__ "__main__" dizgesine ayarlanır.

  • Dosya başka bir betik tarafından içe aktarıldığında, __name__ modül adına ayarlanır – .py olmadan dosya adı.

Bunu kullanan deyim şudur:

label_util.py

def label(text):
    return "[" + text + "]"

if __name__ == "__main__":
    print(label("self-test"))

Çıktı (doğrudan çalıştırıldığında):

[self-test]

Aynı dosya bunun yerine içe aktarıldığında, __name__ modül adına ayarlanır, bu nedenle if bloğu atlanır ve fazladan hiçbir şey çalışmaz:

>>> import label_util
>>> label_util.__name__
'label_util'

Bu deseni, içe aktaran betikleri rahatsız etmeden bir kütüphane dosyasına hızlı bir duman testi veya demo iliştirmek için kullanın.