Empat bentuk statement import yang kelihatannya serupa ternyata menghasilkan efek yang sangat berbeda pada namespace program kita. Bentuk yang salah membuat nama bertabrakan diam-diam, sementara bentuk yang tepat membuat asal setiap function terbaca jelas. Pada Chapter ini kita membedah keempat bentuk tersebut satu per satu, lalu membuktikan sendiri mengapa satu di antaranya — star import — dilarang dalam praktik industri.
Empat Bentuk dan Efeknya #
Tabel berikut merangkum seluruh bentuk statement import yang perlu dikuasai:
| Bentuk | Contoh | Nama yang tersedia setelahnya |
|---|---|---|
import module | import math | math saja; isinya diakses dengan math.sqrt |
import module as alias | import math as mtk | mtk.sqrt(25) |
from module import nama | from math import sqrt | sqrt(25) langsung, tanpa awalan |
from module import * | from math import * | semua nama publik module, langsung |
Tiga bentuk pertama aman dan lazim dipakai. Bentuk keempat terlihat paling praktis — tidak perlu menulis awalan atau daftar nama — tetapi menyimpan dua masalah besar yang akan kita buktikan sebentar lagi.
Sebelum itu, mari kita pastikan perilaku bentuk from ... import ... sudah sepenuhnya jelas, karena bentuk ini punya dua variasi tambahan yang berguna:
from math import sqrt, pi
from math import floor as bulatkan_bawah
print(sqrt(25))
print(pi)
print(bulatkan_bawah(7.5))Output yang Dihasilkan:
5.0
3.141592653589793
7Beberapa nama bisa diimpor sekaligus dengan koma, dan setiap nama boleh diberi alias sendiri dengan as — pola from math import floor as bulatkan_bawah mengimpor floor dengan nama lokal bulatkan_bawah.
Bahaya Star Import #
Bentuk from math import * menyeret seluruh nama publik module ke dalam program kita secara diam-diam. Kita ukur dampaknya dengan function bawaan dir() yang mencantumkan semua nama di namespace saat ini:
banyak_sebelum = len(dir())
from math import *
banyak_sesudah = len(dir())
print("Nama sebelum star import:", banyak_sebelum)
print("Nama sesudah star import:", banyak_sesudah)
print("sqrt tersedia langsung:", sqrt(2))Output yang Dihasilkan:
Nama sebelum star import: 9
Nama sesudah star import: 71
sqrt tersedia langsung: 1.4142135623730951Satu statement star import menambah 62 nama baru ke namespace program — dan itu hanya dari module math yang relatif kecil. Bayangkan star import dari module besar seperti datetime atau pustaka pihak ketiga: ratusan nama masuk tanpa kita ketahui daftarnya, dan tidak ada yang menahan kita menimpanya tanpa sengaja.
Tabrakan Nama yang Sesungguhnya #
Bencana star import dan from import terjadi ketika nama yang diimpor tertimpa. Perhatikan urutan berikut:
from math import sqrt
print(sqrt(2)) # masih function dari math
sqrt = 10 # tanpa sengaja menimpa nama sqrt
print(sqrt) # kini berisi angka
print(sqrt(2)) # bukan function lagiOutput yang Dihasilkan:
1.4142135623730951
10
Traceback (most recent call last):
File "/home/budi/belajar/tabrakan.py", line 9, in <module>
print(sqrt(2)) # bukan function lagi
^^^^^^^
TypeError: 'int' object is not callablePenjelasan lengkap jalur file di traceback di atas mengikuti komputer tempat program dijalankan — di mesin Anda isinya akan berbeda, tetapi pesan galatnya sama. Mari kita bedah kejadiannya:
- Baris 1 (
from math import sqrt): namasqrtdi program kita diarahkan ke function akar kuadrat milik modulemath. - Baris 5 (
sqrt = 10): penugasan mengubah isi namasqrtmenjadi bilangan10. Import sebelumnya tidak melindungi nama apa pun —sqrthanyalah nama biasa di program kita. - Baris 9 (
print(sqrt(2))): interpreter mencoba “memanggil” angka10seolah-olah function, dan menolaknya denganTypeError: 'int' object is not callable.
Bentuk import math kebal terhadap kejadian ini karena function diakses lewat awalan math.:
import math
sqrt = 10 # hanya menimpa nama lokal kita
print("math.sqrt tetap aman:", math.sqrt(2))
print("sqrt lokal sekarang:", sqrt)Output yang Dihasilkan:
math.sqrt tetap aman: 1.4142135623730951
sqrt lokal sekarang: 10Awalan math. menjaga jarak: nama sqrt milik module math tidak pernah berbagi ruang dengan nama sqrt milik program kita.
Aturan praktisnya ringkas: gunakan import module sebagai bentuk bawaan, import module as alias bila nama panjang atau ada kesepakatan alias, dan from module import nama bila awalan membuat kode bertele-tele — misalnya nama yang dipakai berkali-kali dalam satu file. Dengan empat bentuk ini dikuasai, kita siap membedah bagaimana interpreter menemukan module yang kita impor: lewat daftar lokasi bernama sys.path.