29. Berinteraksi dengan Sistem Operasi: sys dan os
Program Python tidak berjalan dalam ruang hampa—mereka berjalan di atas sistem operasi yang mengelola file, direktori, pengaturan lingkungan, serta cara program dimulai dan berkomunikasi. Modul sys dan os menyediakan alat untuk berinteraksi dengan lingkungan ini, sehingga program kamu bisa menerima argumen command-line, membaca variabel lingkungan, menavigasi sistem file, serta membuat atau menghapus direktori.
Memahami modul-modul ini mengubah skrip Python kamu dari kode yang terisolasi menjadi program yang bisa terintegrasi dengan sistem yang lebih luas, merespons input pengguna saat startup, dan mengelola file serta folder secara terprogram.
29.1) Argumen Command-Line dan Menggunakan sys.argv
Saat kamu menjalankan skrip Python dari terminal atau command prompt, kamu bisa mengirimkan informasi tambahan kepadanya—ini disebut argumen command-line (command-line arguments). Contohnya:
python greet.py Alice 25Di sini, greet.py adalah nama skrip, dan Alice serta 25 adalah argumen yang diteruskan ke program. Modul sys memberi akses ke argumen ini melalui sys.argv, sebuah list yang berisi nama skrip dan semua argumen dalam bentuk string.
29.1.1) Apa itu sys.argv?
sys.argv adalah sebuah list di mana:
sys.argv[0]selalu merupakan nama skrip yang sedang dijalankansys.argv[1],sys.argv[2], dan seterusnya adalah argumen yang diberikan setelah nama skrip- Semua elemennya adalah string, meskipun terlihat seperti angka
Mari buat skrip sederhana untuk melihat cara kerjanya:
# show_args.py
import sys
print("Script name:", sys.argv[0])
print("Number of arguments:", len(sys.argv))
print("All arguments:", sys.argv)Jika kamu menjalankan skrip ini dengan:
python show_args.py hello world 123Output:
Script name: show_args.py
Number of arguments: 4
All arguments: ['show_args.py', 'hello', 'world', '123']Perhatikan bahwa sys.argv berisi 4 elemen: nama skrip ditambah tiga argumen. Angka 123 disimpan sebagai string '123', bukan sebagai integer.
29.1.2) Menggunakan Argumen Command-Line dalam Program
Argumen command-line memungkinkan pengguna menyesuaikan perilaku program tanpa memodifikasi kode. Berikut program salam yang menggunakan argumen pertama sebagai nama:
# greet.py
import sys
if len(sys.argv) < 2:
print("Usage: python greet.py <name>")
sys.exit(1) # Keluar dengan kode error
name = sys.argv[1]
print(f"Hello, {name}!")Menjalankan ini:
python greet.py AliceOutput:
Hello, Alice!Jika kamu lupa menyediakan nama:
python greet.pyOutput:
Usage: python greet.py <name>Program memeriksa apakah argumen yang diberikan sudah cukup. Jika tidak, program mencetak pesan penggunaan dan keluar dengan sys.exit(1). Angka 1 adalah sebuah kode keluar (exit code)—secara konvensi, 0 berarti sukses dan nilai non-zero menandakan error. Ini membantu program atau skrip lain mendeteksi apakah program kamu berjalan dengan sukses.
29.1.3) Mengonversi Argumen ke Tipe Lain
Karena semua argumen masuk sebagai string, kamu sering perlu mengonversinya. Berikut program yang menghitung luas persegi panjang:
# area.py
import sys
if len(sys.argv) < 3:
print("Usage: python area.py <width> <height>")
sys.exit(1)
try:
width = float(sys.argv[1])
height = float(sys.argv[2])
except ValueError:
print("Error: Width and height must be numbers")
sys.exit(1)
area = width * height
print(f"Area: {area}")Menjalankan ini:
python area.py 5.5 3.2Output:
Area: 17.6Jika pengguna memberikan input yang tidak valid:
python area.py five threeOutput:
Error: Width and height must be numbersBlok try-except (dari Bab 25) menangani error konversi dengan baik, memberikan umpan balik yang membantu alih-alih crash dengan traceback.
29.2) Mendapatkan Informasi Interpreter dan Runtime dengan sys
Modul sys menyediakan informasi tentang interpreter Python itu sendiri dan environment runtime. Ini berguna untuk debugging, logging, atau menulis kode yang beradaptasi dengan versi Python atau platform yang berbeda.
29.2.1) Informasi Versi Python
sys.version dan sys.version_info memberi tahu kamu versi Python mana yang sedang menjalankan kode:
import sys
print("Python version string:", sys.version)
print("Version info:", sys.version_info)
print(f"Major version: {sys.version_info.major}")
print(f"Minor version: {sys.version_info.minor}")Output (contoh):
Python version string: 3.11.4 (main, Jul 5 2023, 13:45:01) [GCC 11.2.0]
Version info: sys.version_info(major=3, minor=11, micro=4, releaselevel='final', serial=0)
Major version: 3
Minor version: 11sys.version adalah string yang mudah dibaca manusia, sedangkan sys.version_info adalah named tuple yang bisa kamu bandingkan secara terprogram:
import sys
if sys.version_info < (3, 8):
print("This program requires Python 3.8 or higher")
sys.exit(1)
print("Python version is compatible")Ini memastikan program kamu hanya berjalan pada versi Python yang didukung.
29.2.2) Informasi Platform
sys.platform mengidentifikasi sistem operasi:
import sys
print("Platform:", sys.platform)
if sys.platform == "win32":
print("Running on Windows")
elif sys.platform == "darwin":
print("Running on macOS")
elif sys.platform.startswith("linux"):
print("Running on Linux")
else:
print("Running on another platform")Output (di Linux):
Platform: linux
Running on LinuxIni memungkinkan kamu menulis kode spesifik platform ketika diperlukan, misalnya menggunakan path file atau perintah sistem yang berbeda.
29.2.3) Path Pencarian Modul
sys.path adalah list direktori yang dicari Python saat kamu mengimpor modul:
import sys
print("Module search paths:")
for path in sys.path:
print(f" {path}")Output (contoh):
Module search paths:
/home/user/projects
/usr/lib/python3.11
/usr/lib/python3.11/lib-dynload
/home/user/.local/lib/python3.11/site-packagesEntri pertama biasanya adalah direktori yang berisi skrip kamu. Python mencari path ini secara berurutan ketika kamu menggunakan import. Memahami sys.path membantu melakukan debugging error impor atau menambahkan direktori modul kustom.
29.2.4) Keluar dari Program dengan Kode Keluar
Kita sudah melihat sys.exit() digunakan untuk menghentikan program. Kamu bisa memberikan kode keluar untuk menunjukkan sukses atau gagal:
import sys
def process_data(filename):
try:
with open(filename) as f:
data = f.read()
# Memproses data...
return True
except FileNotFoundError:
print(f"Error: File '{filename}' not found", file=sys.stderr)
return False
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python script.py <filename>", file=sys.stderr)
sys.exit(1)
success = process_data(sys.argv[1])
sys.exit(0 if success else 1)Kode keluar mengikuti konvensi Unix:
0berarti sukses- Nilai non-zero menandakan jenis error yang berbeda
- Program lain bisa memeriksa kode ini untuk menentukan apakah program kamu berhasil
29.3) Mengakses Variabel Lingkungan dengan os
Variabel lingkungan (environment variables) adalah pasangan key-value yang diatur oleh sistem operasi atau pengguna dan dapat dibaca oleh program. Ini digunakan untuk konfigurasi, menyimpan path, API key, dan pengaturan lain yang sebaiknya tidak di-hardcode.
29.3.1) Membaca Variabel Lingkungan
Modul os menyediakan os.environ, objek mirip dictionary yang berisi semua variabel lingkungan:
import os
# Mengambil variabel lingkungan tertentu
home = os.environ.get('HOME') # Pada Unix/Linux/macOS
print(f"Home directory: {home}")
# Mengembalikan None jika variabelnya tidak ada
api_key = os.environ.get('MY_API_KEY')
print(f"API key: {api_key}")Output (di Linux):
Home directory: /home/alice
API key: NoneKamu bisa memberikan nilai default:
import os
# Mengambil variabel lingkungan dengan default
log_level = os.environ.get('LOG_LEVEL', 'INFO')
print(f"Log level: {log_level}")Output (jika LOG_LEVEL tidak diset):
Log level: INFO29.3.2) Variabel Lingkungan yang Umum
Sistem operasi yang berbeda menyediakan variabel lingkungan standar:
import os
# Variabel lintas platform
print("Path:", os.environ.get('PATH'))
# Unix/Linux/macOS
print("User:", os.environ.get('USER'))
print("Home:", os.environ.get('HOME'))
print("Shell:", os.environ.get('SHELL'))
# Windows
print("User", os.environ.get('USERNAME'))
print("User Profile:", os.environ.get('USERPROFILE'))
print("Temp:", os.environ.get('TEMP'))PATH sangat penting—ini berisi daftar direktori tempat sistem mencari program executable. Saat kamu mengetik perintah seperti python, sistem mencari di direktori-direktori ini.
29.3.3) Mengatur Variabel Lingkungan
Kamu bisa memodifikasi variabel lingkungan untuk program kamu dan subprocess apa pun yang dibuatnya:
import os
# Mengatur variabel lingkungan
os.environ['MY_CONFIG'] = 'production'
# Membacanya kembali
print(os.environ.get('MY_CONFIG')) # Output: production
# Menghapus variabel lingkungan
del os.environ['MY_CONFIG']Penting: Perubahan pada os.environ hanya memengaruhi proses Python saat ini dan program apa pun yang diluncurkannya. Perubahan ini tidak bertahan setelah program kamu selesai atau memengaruhi program lain.
29.4) Bekerja dengan Path File dan Direktori (os.path, os.getcwd)
Mengelola path file dengan benar itu krusial untuk program yang bekerja dengan file. Modul os dan os.path menyediakan alat untuk membangun, memanipulasi, dan mengecek path dengan cara yang independen dari platform.
29.4.1) Mendapatkan Direktori Kerja Saat Ini
Direktori kerja saat ini (current working directory/CWD) adalah folder yang dianggap program kamu sebagai titik awal untuk path relatif:
import os
cwd = os.getcwd()
print(f"Current working directory: {cwd}")Output (contoh):
Current working directory: /home/alice/projects/myappSaat kamu membuka file dengan path relatif seperti 'data.txt', Python mencari di direktori kerja saat ini. Memahami CWD membantu melakukan debugging error "file not found".
29.4.2) Mengubah Direktori Saat Ini
Kamu bisa mengubah direktori kerja dengan os.chdir():
import os
original = os.getcwd()
print("Original directory:", original)
# Mengubah ke direktori lain
os.chdir('/tmp')
print("New directory:", os.getcwd())
# Mengubah kembali
os.chdir(original)
print("Back to:", os.getcwd())Output:
Original directory: /home/alice/projects
New directory: /tmp
Back to: /home/alice/projectsCatatan: Pada Bab 28, kamu belajar tentang contextlib.chdir(), yang secara otomatis mengembalikan direktori asli. Untuk perubahan direktori yang sederhana, lebih baik gunakan context manager:
from contextlib import chdir
with chdir('/tmp'):
print("Temporarily in:", os.getcwd())
# Automatically restoredIni memastikan direktori selalu dipulihkan, bahkan jika terjadi error.
29.4.3) Membangun Path dengan os.path.join()
Sistem operasi yang berbeda menggunakan pemisah path yang berbeda:
- Unix/Linux/macOS:
/(forward slash) - Windows:
\(backslash)
os.path.join() membangun path dengan benar untuk platform saat ini:
import os
# Membuat path ke file dalam subdirektori
data_dir = 'data'
filename = 'users.txt'
filepath = os.path.join(data_dir, filename)
print(f"File path: {filepath}")Output (di Unix/Linux/macOS):
File path: data/users.txtOutput (di Windows):
File path: data\users.txtKamu bisa menggabungkan beberapa komponen:
import os
base = '/home/alice'
project = 'myapp'
subdir = 'data'
file = 'config.json'
full_path = os.path.join(base, project, subdir, file)
print(full_path) # Output: /home/alice/myapp/data/config.jsonMenggunakan os.path.join() membuat kode kamu portabel di berbagai sistem operasi.
29.4.4) Mengecek Apakah Path Ada
Sebelum bekerja dengan file atau direktori, cek apakah mereka ada:
import os
path = 'data.txt'
if os.path.exists(path):
print(f"'{path}' exists")
else:
print(f"'{path}' does not exist")Kamu juga bisa mengecek secara spesifik untuk file atau direktori:
import os
path = 'mydir'
if os.path.isfile(path):
print(f"'{path}' is a file")
elif os.path.isdir(path):
print(f"'{path}' is a directory")
elif os.path.exists(path):
print(f"'{path}' exists but is neither a file nor directory")
else:
print(f"'{path}' does not exist")Pengecekan ini mencegah error saat mencoba membuka file yang tidak ada atau menampilkan isi direktori yang tidak ada.
29.4.5) Mendapatkan Path Absolut
os.path.abspath() mengonversi path relatif menjadi path absolut:
import os
relative_path = 'data/users.txt'
absolute_path = os.path.abspath(relative_path)
print(f"Relative: {relative_path}")
print(f"Absolute: {absolute_path}")Output (contoh):
Relative: data/users.txt
Absolute: /home/alice/projects/myapp/data/users.txtIni berguna untuk logging, pesan error, atau saat kamu perlu tahu lokasi tepat sebuah file.
29.4.6) Memecah Path menjadi Komponen
os.path.split() memisahkan sebuah path menjadi direktori dan nama file:
import os
path = '/home/alice/projects/data.txt'
directory, filename = os.path.split(path)
print(f"Directory: {directory}")
print(f"Filename: {filename}")Output:
Directory: /home/alice/projects
Filename: data.txtos.path.basename() mengambil hanya nama file, dan os.path.dirname() mengambil hanya direktori:
import os
path = '/home/alice/projects/data.txt'
print(f"Basename: {os.path.basename(path)}") # Output: data.txt
print(f"Dirname: {os.path.dirname(path)}") # Output: /home/alice/projects29.4.7) Memisahkan Ekstensi File
os.path.splitext() memisahkan nama file dari ekstensi:
import os
filename = 'report.pdf'
name, extension = os.path.splitext(filename)
print(f"Name: {name}") # Output: report
print(f"Extension: {extension}") # Output: .pdfIni berguna untuk memproses file berdasarkan tipenya:
import os
files = ['data.csv', 'image.png', 'document.txt', 'script.py']
for file in files:
name, ext = os.path.splitext(file)
if ext == '.csv':
print(f"Process CSV file: {file}")
elif ext == '.png':
print(f"Process image file: {file}")Output:
Process CSV file: data.csv
Process image file: image.png29.5) Menampilkan Daftar, Membuat, dan Menghapus File serta Direktori
Modul os menyediakan fungsi untuk memanipulasi sistem file: menampilkan isi direktori, membuat direktori baru, dan menghapus file serta folder.
29.5.1) Menampilkan Isi Direktori
os.listdir() mengembalikan list semua item di dalam sebuah direktori:
import os
# Menampilkan isi direktori saat ini
contents = os.listdir('.')
print("Current directory contents:")
for item in contents:
print(f" {item}")Output (contoh):
Current directory contents:
script.py
data.txt
mydir
README.mdList ini mencakup file dan direktori. Untuk membedakan keduanya:
import os
contents = os.listdir('.')
print("Files:")
for item in contents:
if os.path.isfile(item):
print(f" {item}")
print("\nDirectories:")
for item in contents:
if os.path.isdir(item):
print(f" {item}")Output:
Files:
script.py
data.txt
README.md
Directories:
mydir29.5.2) Membuat Direktori
os.mkdir() membuat satu direktori:
import os
new_dir = 'output'
if not os.path.exists(new_dir):
os.mkdir(new_dir)
print(f"Created directory: {new_dir}")
else:
print(f"Directory already exists: {new_dir}")Output:
Created directory: outputPenting: os.mkdir() gagal jika direktori induk tidak ada. Misalnya, mencoba membuat 'data/output' saat 'data' tidak ada akan memunculkan error.
os.makedirs() membuat semua direktori induk yang diperlukan:
import os
nested_dir = 'data/processed/2024'
if not os.path.exists(nested_dir):
os.makedirs(nested_dir)
print(f"Created directory structure: {nested_dir}")Output:
Created directory structure: data/processed/2024Ini membuat data, lalu data/processed, lalu data/processed/2024 jika belum ada.
29.5.3) Menghapus File
os.remove() menghapus sebuah file:
import os
filename = 'temp.txt'
# Membuat file sementara
with open(filename, 'w') as f:
f.write('Temporary data')
print(f"File exists: {os.path.exists(filename)}") # Output: True
# Menghapus file
os.remove(filename)
print(f"File exists: {os.path.exists(filename)}") # Output: FalsePeringatan: os.remove() menghapus file secara permanen—file tidak masuk ke recycle bin.
29.5.4) Menghapus Direktori
os.rmdir() menghapus direktori kosong:
import os
directory = 'empty_dir'
# Membuat lalu menghapus direktori kosong
os.mkdir(directory)
print(f"Created: {directory}")
os.rmdir(directory)
print(f"Removed: {directory}")os.rmdir() gagal jika direktori berisi file. Untuk menghapus direktori beserta semua isinya, kamu perlu menghapus file terlebih dahulu:
import os
def remove_directory_contents(directory):
"""Menghapus semua file dalam sebuah direktori, lalu menghapus direktorinya.
Catatan: Gagal jika direktori berisi subdirektori.
"""
if not os.path.exists(directory):
print(f"Directory does not exist: {directory}")
return
# Menghapus semua file di dalam direktori
for item in os.listdir(directory):
item_path = os.path.join(directory, item)
if os.path.isfile(item_path):
os.remove(item_path)
print(f"Removed file: {item_path}")
# Menghapus direktori yang sekarang sudah kosong
os.rmdir(directory)
print(f"Removed directory: {directory}")
# Contoh penggunaan
test_dir = 'test_data'
os.makedirs(test_dir, exist_ok=True)
# Membuat beberapa file uji
with open(os.path.join(test_dir, 'file1.txt'), 'w') as f:
f.write('test')
with open(os.path.join(test_dir, 'file2.txt'), 'w') as f:
f.write('test')
# Menghapus semuanya
remove_directory_contents(test_dir)Output:
Removed file: test_data/file1.txt
Removed file: test_data/file2.txt
Removed directory: test_dataCatatan: Untuk penghapusan direktori yang lebih kompleks (termasuk subdirektori), modul shutil Python menyediakan shutil.rmtree(), tetapi itu di luar cakupan kita saat ini.
29.5.5) Mengganti Nama File dan Direktori
os.rename() mengganti nama atau memindahkan file dan direktori:
import os
# Mengganti nama file
old_name = 'draft.txt'
new_name = 'final.txt'
# Membuat file uji
with open(old_name, 'w') as f:
f.write('content')
os.rename(old_name, new_name)
print(f"Renamed '{old_name}' to '{new_name}'")Kamu juga bisa memindahkan file ke direktori yang berbeda:
import os
# Membuat direktori dan file
os.makedirs('source', exist_ok=True)
os.makedirs('destination', exist_ok=True)
with open('source/file.txt', 'w') as f:
f.write('content')
# Memindahkan file ke direktori lain
os.rename('source/file.txt', 'destination/file.txt')
print("Moved file to destination directory")Modul sys dan os memberi program Python kamu kemampuan untuk berinteraksi dengan sistem operasi, menerima input command-line, membaca konfigurasi, serta mengelola file dan direktori. Kemampuan ini mengubah skrip sederhana menjadi alat command-line yang kuat yang terintegrasi mulus dengan lingkungan sistem yang lebih luas.