Python betiklerinizi daha etkileşimli ve esnek hale getirmek mi istiyorsunuz? Komut satırı argümanları, kullanıcıların programlarınıza doğrudan veri girişi yapmasını sağlayarak bu dinamizmi sunar. Bu makale, Python’da komut satırı argümanlarını işlemenin temel yöntemleri olan sys.argv, argparse ve getopt modüllerini adım adım inceleyecek, böylece uygulamalarınızı çok daha güçlü hale getirebileceksiniz.
Python Komut Satırı Argümanları Neden Önemlidir?
Bir Python betiği yazdığınızda, genellikle belirli bir görevi yerine getirmesini beklersiniz. Ancak bu görevin her zaman aynı verilerle mi çalışması gerekiyor? Ya da kullanıcının her seferinde betiğin içine girip bir değişkenin değerini değiştirmesi mi gerekecek? İşte bu noktada komut satırı argümanları devreye girer ve betiklerinizi dışarıdan kontrol edilebilir, yeniden kullanılabilir ve çok daha esnek hale getirir. Örneğin, bir dosya işleme betiği yazdığınızı düşünün. Bu betiğin her seferinde aynı dosyayı işlemesi yerine, kullanıcıların komut satırından hangi dosyayı işleyeceğini belirtmesi çok daha pratik olmaz mıydı? Veya bir veri analizi aracı geliştirirken, analiz türünü, çıktı formatını veya eşik değerlerini doğrudan komut satırından ayarlamak, betiğinizin kullanım kolaylığını önemli ölçüde artırır. Bu yaklaşım, sadece geliştiriciler için değil, aynı zamanda son kullanıcılar için de büyük kolaylık sağlar; zira programın davranışını değiştirmek için kod bilgisine sahip olmaları gerekmez. Böylelikle, betikleriniz daha genel amaçlı araçlara dönüşür ve farklı senaryolara kolayca adapte edilebilir.
Komut satırı argümanları, özellikle otomasyon betikleri, veri işleme araçları ve daha büyük sistemlerin parçası olan yardımcı programlar için vazgeçilmezdir. Bir betiği bir zamanlayıcı (cron job) ile çalıştırırken veya başka bir programdan çağırırken, parametreleri doğrudan iletebilmek, iş akışlarını otomatikleştirmenin anahtarıdır. Bu sayede, manuel müdahaleye gerek kalmadan karmaşık görevler seri bir şekilde yürütülebilir. Ayrıca, komut satırı arayüzleri (CLI), özellikle sunucu ortamlarında veya grafik arayüzü olmayan sistemlerde programlarla etkileşim kurmanın birincil yoludur. Bu bağlamda, Python’ın sunduğu modüller, geliştiricilere bu tür dinamik ve güçlü CLI uygulamaları oluşturma yeteneği verir. Şimdi, bu argümanları Python’da nasıl yakalayacağımıza ve işleyeceğimize yakından bakalım.
Python’da Komut Satırı Argümanları Nasıl Yakalanır: sys.argv Modülü
Python’da komut satırı argümanlarını işlemenin en temel yolu, yerleşik sys modülünün argv özniteliğini kullanmaktır. sys.argv, bir liste (list) yapısıdır ve betiğiniz çalıştırıldığında komut satırında belirtilen tüm argümanları içerir. Bu listenin ilk elemanı (yani sys.argv[0]), her zaman çalıştırılan Python betiğinin adıdır. Diğer elemanlar ise sırasıyla komut satırında betik adından sonra gelen argümanlardır. Bu basit yapı, hızlı ve az sayıda argüman içeren betikler için oldukça kullanışlıdır, ancak daha karmaşık senaryolarda bazı sınırlamaları vardır. Örneğin, argümanların tip kontrolünü veya varsayılan değerlerini otomatik olarak yönetmez; bu gibi kontrolleri manuel olarak kodlamak gerekir. Ayrıca, kullanıcılara yönelik yardımcı mesajlar veya hata denetimi gibi özellikler de doğrudan sys.argv tarafından sağlanmaz, bu da daha büyük uygulamalarda geliştiriciye ek yük bindirir.
Şimdi sys.argv‘nin nasıl çalıştığını gösteren basit bir örnekle konuyu pekiştirelim. Bir dosya adını komut satırından alıp o dosyanın kaç satır içerdiğini sayan bir betik yazalım. Bu, genellikle bir veri analizi veya günlük dosyası işleme görevinin ilk adımı olabilir.
import sys
def satir_sayici(dosya_yolu):
"""Belirtilen dosyadaki satır sayısını döndürür."""
try:
with open(dosya_yolu, 'r', encoding='utf-8') as f:
satir_sayisi = sum(1 for line in f)
return satir_sayisi
except FileNotFoundError:
print(f"Hata: '{dosya_yolu}' dosyası bulunamadı.")
return -1
except Exception as e:
print(f"Dosya okunurken bir hata oluştu: {e}")
return -1
if __name__ == "__main__":
if len(sys.argv) > 1:
dosya_adi = sys.argv[1]
print(f"'{dosya_adi}' dosyası işleniyor...")
sayi = satir_sayici(dosya_adi)
if sayi != -1:
print(f"'{dosya_adi}' dosyasında {sayi} satır bulunmaktadır.")
else:
print("Kullanım: python satir_say.py <dosya_adi>")
print("Örnek: python satir_say.py metin.txt")
Yukarıdaki kodu satir_say.py adıyla kaydedip komut satırından şu şekilde çalıştırabilirsiniz:
python satir_say.py metin.txt
Eğer metin.txt adında bir dosya varsa, betik bu dosyanın satır sayısını gösterecektir. Yoksa, bir hata mesajı alacaksınız. Eğer hiç argüman vermeden çalıştırırsanız:
python satir_say.py
Betiğiniz size nasıl kullanmanız gerektiğini açıklayan bir mesaj gösterecektir. Gördüğünüz gibi, sys.argv ile temel argüman işleme kolayca yapılabilir. Ancak, argümanların sırası önemlidir ve eğer çok sayıda argümanınız varsa veya isteğe bağlı argümanlar eklemek isterseniz, kodunuz hızla karmaşıklaşabilir. Bu durumda, argparse gibi daha gelişmiş bir modüle ihtiyaç duyulur. sys.argv, genellikle betiğin hızlıca bir veya iki zorunlu argüman alması gereken durumlarda veya diğer daha gelişmiş argüman işleme modüllerinin temelini anlamak için iyi bir başlangıç noktasıdır.
Gelişmiş Argüman İşleme: argparse Modülü Nasıl Kullanılır?
Python’da komut satırı argümanlarını işlemenin en güçlü ve esnek yolu argparse modülüdür. Büyük ve karmaşık uygulamalar geliştirirken, sys.argv‘nin sunduğu basitliğin ötesine geçmek kaçınılmaz hale gelir. argparse, argümanları ayrıştırma, tip kontrolü yapma, varsayılan değerler atama, yardımcı (help) mesajları oluşturma ve hatta argüman grupları ile alt komutlar tanımlama gibi birçok gelişmiş özelliği otomatik olarak yönetir. Bu modül, özellikle kullanıcı dostu ve sağlam komut satırı arayüzleri (CLI) oluşturmak isteyen geliştiriciler için biçilmiş kaftandır. argparse sayesinde, kullanıcılar programınızı doğru bir şekilde kullanmak için gerekli tüm bilgilere (hangi argümanların zorunlu olduğu, hangi tipte veri beklediği, ne işe yaradığı vb.) kolayca erişebilirler. Bu, hem geliştirme sürecini hızlandırır hem de son kullanıcı deneyimini önemli ölçüde iyileştirir.
argparse ile Temel Argüman Tanımlama
argparse kullanmaya başlamak için öncelikle bir ArgumentParser nesnesi oluşturmanız gerekir. Bu nesne, betiğinizin argümanlarını nasıl yorumlayacağını belirleyen temel yapı taşıdır. Ardından, add_argument() metodunu kullanarak betiğinizin kabul edeceği her bir argümanı tanımlarsınız. Bu metot, argümanların adlarını, tiplerini, varsayılan değerlerini, kısa ve uzun versiyonlarını ve hatta yardımcı metinlerini belirlemenizi sağlar. Son olarak, parse_args() metodu ile komut satırından gelen argümanları ayrıştırır ve bir nesne olarak erişilebilir hale getirirsiniz. Bu nesne, tanımladığınız her argümanı bir öznitelik olarak içerir, bu da argümanlara erişimi son derece kolaylaştırır.
Şimdi bir örnekle bu süreci daha iyi anlayalım. Bir dosyadaki kelime sayısını bulan, ancak kullanıcının isterse çıktı formatını değiştirebileceği bir betik hayal edelim. Bu betik, hem zorunlu bir dosya yolu argümanı alacak hem de isteğe bağlı olarak “verbose” (ayrıntılı) bir çıktı bayrağına sahip olacak.
import argparse
import os
def kelime_sayici(dosya_yolu, verbose=False):
"""Belirtilen dosyadaki kelime sayısını döndürür."""
if not os.path.exists(dosya_yolu):
print(f"Hata: '{dosya_yolu}' dosyası bulunamadı.")
return -1
try:
with open(dosya_yolu, 'r', encoding='utf-8') as f:
icerik = f.read()
kelimeler = icerik.split()
sayi = len(kelimeler)
if verbose:
print(f"Dosya yolu: {dosya_yolu}")
print(f"Toplam karakter sayısı: {len(icerik)}")
print(f"Boşluklarla ayrılmış kelimeler: {kelimeler[:10]}...") # İlk 10 kelimeyi göster
return sayi
except Exception as e:
print(f"Dosya okunurken bir hata oluştu: {e}")
return -1
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Bir dosyadaki kelime sayısını bulan betik.")
# Zorunlu pozisyonel argüman: dosya yolu
parser.add_argument("dosya",
help="İşlenecek dosyanın yolu.")
# İsteğe bağlı argüman: ayrıntılı çıktı
parser.add_argument("-v", "--verbose",
action="store_true",
help="Ayrıntılı çıktı gösterir.")
# İsteğe bağlı argüman: çıktı formatı
parser.add_argument("-f", "--format",
choices=['text', 'json'],
default='text',
help="Çıktı formatını belirler (varsayılan: text).")
args = parser.parse_args()
kelime_sayisi = kelime_sayici(args.dosya, args.verbose)
if kelime_sayisi != -1:
if args.format == 'json':
import json
output_data = {
"dosya_adi": args.dosya,
"kelime_sayisi": kelime_sayisi,
"verbose_mod": args.verbose
}
print(json.dumps(output_data, indent=2))
else:
print(f"'{args.dosya}' dosyasında {kelime_sayisi} kelime bulunmaktadır.")
Bu kodu kelime_sayar.py olarak kaydedin. Şimdi çeşitli şekillerde çalıştırabilirsiniz:
python kelime_sayar.py metin.txt: Temel kelime sayımı.python kelime_sayar.py metin.txt -vveyapython kelime_sayar.py metin.txt --verbose: Ayrıntılı çıktı ile kelime sayımı.python kelime_sayar.py metin.txt -f jsonveyapython kelime_sayar.py metin.txt --format json: JSON formatında çıktı.python kelime_sayar.py --help: Otomatik olarak oluşturulan yardım mesajını gösterir. Bu,argparse‘ın en değerli özelliklerinden biridir.
Bu örnekte, argparse‘ın nasıl hem zorunlu hem de isteğe bağlı argümanları, farklı tiplerde (action="store_true" bir bayrak için, choices belirli değerler için) ve varsayılan değerlerle kolayca yönetebildiğini gördük. Ayrıca, otomatik yardım mesajları sayesinde kullanıcının betiğinizi nasıl kullanacağını öğrenmesi çok daha kolay hale gelir. Bu esneklik ve otomasyon, argparse‘ı Python’da komut satırı uygulamaları geliştirmek için standart bir seçim haline getiriyor.
argparse ile Vaka Analizi: Gelişmiş Bir Veri Dönüştürücü
Şimdi, argparse‘ın gerçek dünya uygulamalarında ne kadar güçlü olabileceğini gösteren daha karmaşık bir vaka analizine dalalım. Bir CSV dosyasını farklı formatlara (JSON, XML) dönüştürebilen ve belirli sütunları filtreleyebilen bir veri dönüştürücü betiği geliştirelim. Bu betik, dosya yolu, çıktı formatı, filtreleme sütunu ve filtreleme değeri gibi çeşitli argümanları alacaktır. Ayrıca, kullanıcıların isterlerse sadece belirli sütunları seçmelerine olanak tanıyan bir özellik de ekleyelim. Bu tür bir araç, veri mühendisliği, raporlama veya API entegrasyonları gibi birçok alanda oldukça faydalıdır.
import argparse
import csv
import json
import xml.etree.ElementTree as ET
from xml.dom import minidom
import os
def csv_oku_ve_islem(dosya_yolu, cikti_format, filtre_sutun=None, filtre_deger=None, secili_sutunlar=None):
"""
CSV dosyasını okur, filtreler ve belirtilen formata dönüştürür.
"""
if not os.path.exists(dosya_yolu):
print(f"Hata: '{dosya_yolu}' dosyası bulunamadı.")
return
veri = []
try:
with open(dosya_yolu, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
basliklar = reader.fieldnames
for satir in reader:
# Filtreleme uygula
if filtre_sutun and filtre_deger:
if satir.get(filtre_sutun) != filtre_deger:
continue
# Seçili sütunları al veya tümünü al
islenmis_satir = {}
if secili_sutunlar:
for sutun in secili_sutunlar:
if sutun in satir:
islenmis_satir[sutun] = satir[sutun]
else:
print(f"Uyarı: '{sutun}' sütunu dosyada bulunamadı.")
else:
islenmis_satir = satir
if islenmis_satir: # Boş satırları ekleme (filtreleme sonrası olabilir)
veri.append(islenmis_satir)
except Exception as e:
print(f"CSV dosyası okunurken hata oluştu: {e}")
return
if not veri:
print("Uyarı: İşlenecek veri bulunamadı veya filtreleme sonucu boş.")
return
if cikti_format == 'json':
print(json.dumps(veri, indent=2, ensure_ascii=False))
elif cikti_format == 'xml':
root = ET.Element("veriler")
for idx, satir in enumerate(veri):
item = ET.SubElement(root, f"kayit id=\"{idx+1}\"")
for key, value in satir.items():
child = ET.SubElement(item, key)
child.text = str(value)
# Güzel formatlı XML çıktısı
rough_string = ET.tostring(root, 'utf-8')
reparsed = minidom.parseString(rough_string)
print(reparsed.toprettyxml(indent=" ", encoding="utf-8").decode('utf-8'))
elif cikti_format == 'csv':
# Eğer çıktı formatı CSV ise, orijinal başlıkları koru veya seçili olanları kullan
if secili_sutunlar:
cikti_basliklar = [s for s in secili_sutunlar if s in basliklar]
else:
cikti_basliklar = basliklar
writer = csv.DictWriter(sys.stdout, fieldnames=cikti_basliklar)
writer.writeheader()
writer.writerows(veri)
else:
print("Desteklenmeyen çıktı formatı.")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="CSV dosyasını farklı formatlara dönüştürür ve filtreler.")
parser.add_argument("dosya", help="İşlenecek CSV dosyasının yolu.")
parser.add_argument("-f", "--format",
choices=['json', 'xml', 'csv'],
default='json',
help="Çıktı formatı (varsayılan: json).")
parser.add_argument("--filtre-sutun",
help="Hangi sütuna göre filtreleme yapılacağını belirtir.")
parser.add_argument("--filtre-deger",
help="Filtreleme yapılacak sütundaki değer.")
parser.add_argument("-s", "--secili-sutunlar",
nargs='+', # Bir veya daha fazla değer almasını sağlar
help="Çıktıda gösterilecek sütun adları (boşlukla ayrılmış).")
args = parser.parse_args()
# Filtreleme argümanlarının birlikte kullanıldığından emin ol
if (args.filtre_sutun and not args.filtre_deger) or (not args.filtre_sutun and args.filtre_deger):
parser.error("--filtre-sutun ve --filtre-deger birlikte kullanılmalıdır.")
csv_oku_ve_islem(args.dosya, args.format, args.filtre_sutun, args.filtre_deger, args.secili_sutunlar)
Bu betiği veri_donusturucu.py olarak kaydedin. Çalıştırmak için örnek bir veri.csv dosyasına ihtiyacımız olacak:
id,ad,sehir,yas
1,Ali,Ankara,30
2,Ayşe,İstanbul,24
3,Can,İzmir,35
4,Deniz,Ankara,28
Şimdi farklı senaryoları deneyelim:
python veri_donusturucu.py veri.csv: Tüm veriyi JSON formatında gösterir.python veri_donusturucu.py veri.csv -f xml: Tüm veriyi XML formatında gösterir.python veri_donusturucu.py veri.csv --filtre-sutun sehir --filtre-deger Ankara: Sadece ‘sehir’ sütunu ‘Ankara’ olan kayıtları JSON olarak gösterir.python veri_donusturucu.py veri.csv -f csv -s ad yas: Sadece ‘ad’ ve ‘yas’ sütunlarını CSV formatında gösterir.python veri_donusturucu.py veri.csv --filtre-sutun sehir --filtre-deger Ankara -f xml -s ad yas: Ankara’daki kişilerin sadece ad ve yaş bilgilerini XML olarak gösterir.
Bu vaka analizinde, argparse‘ın nasıl karmaşık iş mantığını destekleyen çok sayıda argümanı (zorunlu, isteğe bağlı, seçimli, birden çok değer alan) kolayca yönetebildiğini gördük. Özellikle nargs='+' kullanımı, birden fazla sütun adını almayı sağlarken, choices parametresi de kullanıcı girişini belirli değerlerle sınırlayarak hata olasılığını azaltır. Bu sayede, geliştirilen araç hem güçlü hem de kullanıcı dostu bir yapıya bürünür.
Geleneksel Yaklaşım: getopt Modülü ve Kullanım Alanları
Python’da komut satırı argümanlarını işlemenin bir diğer yöntemi de getopt modülüdür. Bu modül, C/C++ programlama dillerindeki aynı isimli POSIX standardı getopt() fonksiyonuna benzer bir arayüz sunar. getopt, özellikle daha eski sistemlerle uyumluluk gerektiren veya POSIX standartlarına sıkı sıkıya bağlı kalmak isteyen projelerde tercih edilebilir. Ancak, argparse‘a kıyasla daha az esneklik ve daha fazla manuel kodlama gerektirir. Örneğin, getopt ile argüman tiplerini kontrol etmek, varsayılan değerler atamak veya otomatik yardım mesajları oluşturmak için ek kod yazmanız gerekir. Bu da, geliştirme sürecini uzatabilir ve kodun okunabilirliğini azaltabilir.
getopt modülü, kısa (tek tireli, örn: -o) ve uzun (çift tireli, örn: --output) seçenekleri ayrıştırmak için tasarlanmıştır. getopt.getopt() fonksiyonu iki ana argüman alır: işlenecek argüman listesi (genellikle sys.argv[1:]) ve kabul edilecek kısa seçenekler ile uzun seçenekler listeleri. Fonksiyon, iki liste döndürür: ayrıştırılmış seçenekler ((seçenek, değer) çiftleri) ve ayrıştırılmamış kalan argümanlar. Bu kalan argümanlar genellikle pozisyonel argümanlardır.
Şimdi, getopt kullanarak basit bir dosya işleme betiği oluşturalım. Bu betik, bir giriş dosyası alacak ve isteğe bağlı olarak bir çıktı dosyası belirleyebilecek. Ayrıca, bir “force” (zorla) bayrağı ile mevcut çıktı dosyasının üzerine yazma izni verecek.
import sys
import getopt
def dosya_isle(giris_dosya, cikis_dosya=None, force=False):
"""
Belirtilen giriş dosyasını işler ve isteğe bağlı olarak çıktı dosyasına yazar.
"""
print(f"Giriş dosyası: {giris_dosya}")
if cikis_dosya:
print(f"Çıkış dosyası: {cikis_dosya}")
if force:
print("Mevcut çıktı dosyası üzerine yazmaya izin verildi.")
# Gerçek dosya işleme mantığı buraya gelir
try:
with open(giris_dosya, 'r', encoding='utf-8') as infile:
icerik = infile.read()
print(f"'{giris_dosya}' dosyasından {len(icerik)} karakter okundu.")
if cikis_dosya:
if os.path.exists(cikis_dosya) and not force:
print(f"Hata: '{cikis_dosya}' zaten mevcut. Üzerine yazmak için -f veya --force kullanın.")
return
with open(cikis_dosya, 'w', encoding='utf-8') as outfile:
outfile.write(icerik.upper()) # Örnek: İçeriği büyük harfe çevirip yaz
print(f"İçerik '{cikis_dosya}' dosyasına yazıldı.")
except FileNotFoundError:
print(f"Hata: '{giris_dosya}' dosyası bulunamadı.")
except Exception as e:
print(f"Dosya işlenirken bir hata oluştu: {e}")
def yardim_mesaji():
print("Kullanım: python getopt_ornek.py -i [-o ] [-f]")
print(" -i, --input Giriş dosyası yolu (zorunlu)")
print(" -o, --output Çıkış dosyası yolu (isteğe bağlı)")
print(" -f, --force Mevcut çıktı dosyasının üzerine yazmaya zorlar")
print(" -h, --help Bu yardım mesajını gösterir")
if __name__ == "__main__":
giris_dosya = None
cikis_dosya = None
force = False
try:
# Kısa seçenekler: i: (değer alır), o: (değer alır), f (bayrak), h (bayrak)
# Uzun seçenekler: input= (değer alır), output= (değer alır), force (bayrak), help (bayrak)
opts, args = getopt.getopt(sys.argv[1:], "i:o:fh", ["input=", "output=", "force", "help"])
except getopt.GetoptError as err:
print(err)
yardim_mesaji()
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--help"):
yardim_mesaji()
sys.exit()
elif opt in ("-i", "--input"):
giris_dosya = arg
elif opt in ("-o", "--output"):
cikis_dosya = arg
elif opt in ("-f", "--force"):
force = True
if not giris_dosya:
print("Hata: Giriş dosyası belirtilmelidir.")
yardim_mesaji()
sys.exit(2)
dosya_isle(giris_dosya, cikis_dosya, force)
Bu kodu getopt_ornek.py olarak kaydedin ve örnek bir input.txt dosyası oluşturun:
Merhaba dünya!
Bu bir deneme metnidir.
Şimdi betiği çalıştıralım:
python getopt_ornek.py -i input.txt: Sadece giriş dosyasını işler.python getopt_ornek.py --input input.txt --output output.txt: Giriş dosyasını okur, içeriği büyük harfe çevirir veoutput.txtdosyasına yazar.python getopt_ornek.py -i input.txt -o output.txt -f: Eğeroutput.txtzaten varsa, üzerine yazmaya zorlar.python getopt_ornek.py -hveyapython getopt_ornek.py --help: Yardım mesajını gösterir.
Gördüğünüz gibi, getopt ile argümanları ayrıştırmak mümkündür, ancak argparse‘taki gibi otomatik yardım mesajları veya tip kontrolü gibi özellikler yoktur. Bu tür kontrolleri ve kullanıcı dostu mesajları elle yazmanız gerekir. Bu nedenle, yeni projelerde veya daha karmaşık CLI uygulamalarında genellikle argparse tercih edilirken, getopt daha çok belirli uyumluluk gereksinimleri olan durumlar için bir alternatif olarak düşünülebilir. Ancak, her iki modül de komut satırı argümanlarının gücünü Python betiklerinize taşımak için önemli araçlardır.
İleri Düzey İpuçları ve En İyi Uygulamalar
Python’da komut satırı argümanlarıyla çalışırken, sadece modülleri kullanmayı bilmekle kalmayıp, aynı zamanda uygulamalarınızı daha sağlam, güvenli ve kullanıcı dostu hale getirecek bazı ileri düzey ipuçlarını ve en iyi uygulamaları da göz önünde bulundurmak önemlidir. Bu, özellikle karmaşık betikler veya uzun ömürlü CLI araçları geliştirirken kritik hale gelir.
1. Argüman Doğrulama ve Özel Tipler
argparse modülü, type parametresi ile argümanların veri tiplerini (int, float vb.) otomatik olarak kontrol edebilir. Ancak bazen daha karmaşık doğrulama kurallarına ihtiyacınız olabilir. Örneğin, bir dosya yolunun gerçekten var olup olmadığını veya bir sayının belirli bir aralıkta olup olmadığını kontrol etmek isteyebilirsiniz. Bunun için kendi özel doğrulama fonksiyonlarınızı yazıp type parametresine atayabilirsiniz:
import argparse
import os
def var_olan_dosya(yol):
if not os.path.exists(yol):
raise argparse.ArgumentTypeError(f"'{yol}' dosyası bulunamadı.")
return yol
parser = argparse.ArgumentParser()
parser.add_argument("--input", type=var_olan_dosya, help="Var olan bir dosyanın yolu.")
# Kullanım: python betik.py --input /var/log/app.log
Bu yaklaşım, kullanıcıların hatalı girdi sağlamasını engeller ve betiğinizin daha güvenilir çalışmasını sağlar. Ayrıca, argparse‘ın choices parametresi ile belirli bir değer kümesi arasından seçim yapılmasını zorlayarak da doğrulama yapabilirsiniz, önceki örneklerde bunu görmüştük.
2. Alt Komutlar ile Karmaşık CLI Yapıları
Büyük uygulamalar genellikle birden fazla işlevi yerine getirir. Örneğin, bir git aracı git clone, git commit, git push gibi alt komutlara sahiptir. argparse, add_subparsers() metodu ile bu tür alt komut yapılarını kolayca oluşturmanıza olanak tanır. Bu, CLI’nizin modülerliğini artırır ve her bir alt komutun kendi argüman setine sahip olmasını sağlar.
import argparse
parser = argparse.ArgumentParser(description="Uygulama yönetimi aracı.")
subparsers = parser.add_subparsers(dest="komut", help="Kullanılabilir komutlar")
# 'ekle' alt komutu
ekle_parser = subparsers.add_parser("ekle", help="Bir öğe ekler.")
ekle_parser.add_argument("isim", help="Eklenecek öğenin adı.")
ekle_parser.add_argument("--miktar", type=int, default=1, help="Eklenecek miktar.")
# 'sil' alt komutu
sil_parser = subparsers.add_parser("sil", help="Bir öğeyi siler.")
sil_parser.add_argument("id", type=int, help="Silinecek öğenin ID'si.")
args = parser.parse_args()
if args.komut == "ekle":
print(f"'{args.isim}' adlı öğeden {args.miktar} adet eklendi.")
elif args.komut == "sil":
print(f"{args.id} ID'li öğe silindi.")
else:
parser.print_help()
# Kullanım: python betik.py ekle elma --miktar 5
# Kullanım: python betik.py sil 123
Bu yapı, kullanıcıların uygulamanızın farklı işlevlerini daha net bir şekilde anlamasına yardımcı olur ve komut satırı arayüzünüzü daha düzenli hale getirir.
3. Ortam Değişkenleri ve Varsayılan Değerler
Bazen komut satırı argümanlarının değerlerini ortam değişkenlerinden almak isteyebilirsiniz. Bu, özellikle hassas bilgiler (API anahtarları gibi) veya sık kullanılan yapılandırma değerleri için kullanışlıdır. argparse doğrudan ortam değişkenlerini okumaz, ancak bunu manuel olarak entegre edebilirsiniz:
import argparse
import os
parser = argparse.ArgumentParser()
parser.add_argument("--api-key",
default=os.environ.get("MY_API_KEY"),
help="API anahtarı (varsayılan olarak MY_API_KEY ortam değişkeninden okunur).")
args = parser.parse_args()
if args.api_key:
print(f"Kullanılan API Anahtarı: {args.api_key}")
else:
print("API Anahtarı belirtilmedi.")
# Kullanım: MY_API_KEY=abc123 python betik.py
# Veya: python betik.py --api-key xyz456
Bu, argümanların esnekliğini artırır ve kullanıcılara değerleri farklı kaynaklardan sağlama imkanı sunar.
4. Mobil Uyumlu HTML ve CLI Uygulamaları
Her ne kadar Python komut satırı uygulamaları doğrudan bir web arayüzüne sahip olmasa da, bu uygulamaların ürettiği çıktılar veya raporlar genellikle web sayfalarında veya e-postalarda sunulabilir. Bu bağlamda, çıktının mobil cihazlarda da düzgün görünmesi önemlidir. HTML çıktısı üreten bir Python betiği yazıyorsanız, mobil uyumluluğu sağlamak için semantik HTML etiketleri kullanmaya özen gösterin. Örneğin, tablolar yerine esnek div yapıları kullanmak veya media query‘ler ile farklı ekran boyutlarına uyum sağlamak önemlidir. Bir media query, CSS kullanarak farklı ekran boyutlarına veya cihaz özelliklerine göre stil kurallarını dinamik olarak uygulamanızı sağlar:
/* Örnek bir CSS media query yapısı */
@media (max-width: 600px) {
/* Ekran genişliği 600 pikselden az olduğunda uygulanacak stiller */
body {
font-size: 14px;
}
table, thead, tbody, th, td, tr {
display: block; /* Tablo elemanlarını blok olarak göster */
}
thead tr {
position: absolute;
top: -9999px;
left: -9999px;
}
tr { border: 1px solid #ccc; }
td {
border: none;
border-bottom: 1px solid #eee;
position: relative;
padding-left: 50%;
}
td:before {
position: absolute;
top: 6px;
left: 6px;
width: 45%;
padding-right: 10px;
white-space: nowrap;
content: attr(data-label); /* Sütun başlığını veri etiketi olarak göster */
}
}
Yukarıdaki CSS örneği, tabloların küçük ekranlarda nasıl daha okunabilir hale getirilebileceğini gösterir. Python betiğinizin ürettiği HTML raporlarında bu tür semantik yapılar ve dış CSS kullanımı, mobil uyumluluğu artıracaktır. Bu, doğrudan Python koduyla ilgili olmasa da, CLI uygulamalarının ürettiği çıktılarla etkileşimde bulunan genel bir en iyi uygulamadır.
Sonuç ve Sıkça Sorulan Sorular
Python’da komut satırı argümanlarını işlemek, betiklerinizi ve uygulamalarınızı daha dinamik, esnek ve kullanıcı dostu hale getirmenin temel bir yoludur. Bu makalede, en basit yöntem olan sys.argv‘den başlayarak, güçlü ve kapsamlı argparse modülüne ve geleneksel getopt modülüne kadar üç farklı yaklaşımı inceledik. sys.argv, hızlı ve temel argüman işleme için yeterli olabilirken, argparse otomatik yardım mesajları, tip kontrolü, varsayılan değerler ve karmaşık CLI yapıları oluşturma yeteneği ile modern Python uygulamaları için standart ve önerilen çözümdür. getopt ise, özellikle POSIX uyumluluğu gerektiren eski projeler için bir alternatif sunar, ancak daha fazla manuel kodlama gerektirir.
Uygulama geliştirirken, projenizin ihtiyaçlarına en uygun modülü seçmek önemlidir. Çoğu durumda, argparse‘ın sunduğu zengin özellik seti ve kullanım kolaylığı, geliştirme sürecinizi büyük ölçüde hızlandıracak ve daha sağlam uygulamalar oluşturmanıza yardımcı olacaktır. İleri düzey ipuçları ve en iyi uygulamalar bölümünde ele aldığımız argüman doğrulama, alt komutlar, ortam değişkeni entegrasyonu ve mobil uyumlu çıktı stratejileri, CLI araçlarınızın kalitesini daha da artıracaktır. Bu bilgilerle donanarak, Python’da güçlü ve etkili komut satırı uygulamaları geliştirmeye hazırsınız.
Sıkça Sorulan Sorular (SSS)
- 1. Hangi modülü ne zaman kullanmalıyım?
-
sys.argv: Çok basit, tek veya iki zorunlu argüman alan, hızlıca yazılmış betikler için idealdir. Yardım mesajları veya tip kontrolü gibi özelliklere ihtiyaç duyulmadığında kullanılabilir.argparse: Modern Python CLI uygulamaları için önerilen standarttır. Zorunlu/isteğe bağlı argümanlar, farklı veri tipleri, varsayılan değerler, otomatik yardım mesajları, argüman grupları ve alt komutlar gibi karmaşık ihtiyaçlarınız olduğunda kullanın. Kullanıcı dostu ve sağlam uygulamalar için en iyi seçimdir.getopt: POSIX uyumluluğu gerektiren veya C/C++’dakigetoptalışkanlığı olan geliştiriciler için bir alternatiftir.argparse‘a göre daha az özellik sunar ve daha fazla manuel kodlama gerektirir. - 2.
argparseile varsayılan değerler nasıl ayarlanır? -
add_argument()metodunu kullanırkendefaultparametresini kullanarak bir argüman için varsayılan bir değer belirleyebilirsiniz. Örneğin:parser.add_argument("--output", default="cikti.txt", help="Çıktı dosyası.") - 3. Komut satırı argümanlarını kullanarak hassas bilgileri (örneğin şifreleri) güvenli bir şekilde nasıl işleyebilirim?
-
Hassas bilgileri doğrudan komut satırı argümanları olarak geçirmek genellikle önerilmez, çünkü bu bilgiler sistem geçmişinde veya süreç listelerinde görünebilir. Bunun yerine, bu tür bilgileri ortam değişkenleri aracılığıyla (
os.environ.get()kullanarak), etkileşimli olarak kullanıcıdan istemek içingetpassmodülünü kullanarak veya güvenli bir yapılandırma dosyasından okuyarak işlemek daha güvenlidir. - 4.
argparse‘ta bir argümanın birden fazla değer almasını nasıl sağlayabilirim? -
add_argument()metodundanargsparametresini kullanabilirsiniz:nargs='*': Sıfır veya daha fazla değer alır.nargs='+': Bir veya daha fazla değer alır.nargs='?': Sıfır veya bir değer alır (genellikle isteğe bağlı bir değer için kullanılır).nargs=N: Tam olarak N adet değer alır.
Örneğin:
parser.add_argument("dosyalar", nargs='+', help="İşlenecek dosyalar.") - 5.
argparseile otomatik olarak oluşturulan yardım mesajını nasıl özelleştirebilirim? -
ArgumentParsernesnesini oluştururkendescriptionveepilogparametrelerini kullanarak genel bir açıklama ve son mesaj ekleyebilirsiniz. Her bir argüman içinhelpparametresi, o argümana özel açıklamayı sağlar. Ayrıca,formatter_classparametresini kullanarak yardım mesajının formatını (örneğin,RawTextHelpFormatterile satır sonlarını koruma) daha da özelleştirebilirsiniz.
