İlk Python Script'in: hello.py'den python -m'e Komut Satırının İncelikleri
İlk gerçek .py dosyanı yazıyorsun. Modül 1'in capstone'u: shebang, encoding declaration, if __name__ == '__main__', python -m flag'i, sys.argv, exit code'lar, .pyc cache, ve her gün karşılaşacağın komut satırı pratikleri. 4 hands-on script ile bitiyoruz.
Şükrü Yusuf KAYA
22 dakikalık okuma
Başlangıç🎉 Modül 1 finali — sonunda 'gerçek' kod yazıyoruz
13 ders boyunca kurulum, sürüm, IDE, REPL — hepsi 'altyapı' idi. Bu derste tüm bu altyapıyı kullanıp ilk gerçek Python script'ini yazıyorsun. Sonra Modül 2'de söz dizimi derinleşir. Tebrikler — bir programcı olma yolculuğunun ilk yarıyılını tamamladın!
Adım 1: hello.py#
Editörünü aç (VS Code önerim), yeni dosya oluştur: . İçine:
hello.pyprint("Merhaba, Python!")
Tek satır. Kaydet. Şimdi terminal'i aç ve dosyanın olduğu klasöre git:
cd ~/Desktop # ya da nereye kaydettiysen python hello.py
Çıktı:
Merhaba, Python!
🎉 Tebrikler — ilk script çalıştı. Bu kadar basit.
"python" mu "python3" mu?#
Sistemine göre değişir. Eğer pyenv kullanıyorsan veya PATH'te Python varsa çalışır. Bazı Linux sistemlerinde sadece var. Eşit alternatifler:
pythonpython3python hello.py python3 hello.py python3.13 hello.py py hello.py # Windows py -3.13 hello.py # Windows, belirli sürüm
Profesyonel script'lerde veya tam sürüm kullanmak hatadan korur.
python3Shebang line — Linux/macOS'ta script'i çalıştırılabilir yapmak#
Linux/macOS'ta script'leri direkt çalıştırılabilir hale getirebilirsin. Bunun için iki şey gerekli:
1. Shebang line#
Dosyanın ilk satırı ile başlamalı. Python script'i için:
#!#!/usr/bin/env python3 print("Merhaba, Python!")
#!/usr/bin/env python3/usr/bin/envpython3Alternatifler:
#!/usr/bin/python3 # Direkt path — port edebilirliği azaltır #!/usr/bin/env python3 # PATH-based — taşınabilir, önerilen #!/usr/bin/env python # python3 yoksa fallback
2. Executable izni#
chmod +x hello.py
Şimdi:
./hello.py # Merhaba, Python!
./Windows'ta shebang?#
Windows shebang'i göz ardı eder; gerek yok. Sadece launcher veya ile çalıştırılır. Ama shebang yazmak zarar vermez — Linux'ta da çalışan bir script yazıyorsan koymalısın.
pypythonEncoding declaration — Türkçe karakter#
Eski Python kodlarında şuna benzeyen 2. satır görürsün:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- print("İstanbul'da yağmur var.")
# -*- coding: utf-8 -*-SyntaxError: Non-ASCII character '\xc4'
Python 3'te default encoding zaten UTF-8. Yani bu satıra gerek yok. Modern Python kodu temiz:
#!/usr/bin/env python3 print("İstanbul'da yağmur var.") # ✅ Sorun yok
Eski legacy kodda görürsen şaşırma — tarihsel artık.
if __name__ == "__main__": — efsane satır#
if __name__ == "__main__":Belki Stack Overflow'da görmüşündür:
def greet(name): print(f"Merhaba, {name}!") if __name__ == "__main__": greet("Dünya")
Bu satır ne yapıyor? Anlaması için Python'un import sistemini bilmen gerek.
Python'da bir dosyası iki şekilde çalıştırılabilir:
.py- Doğrudan: — script olarak.
python hello.py - Import edilerek: Başka bir dosyada — modül olarak.
import hello
__name__- Doğrudan çalıştırıldığında:
__name__ == "__main__" - Import edildiğinde: (dosya adı)
__name__ == "hello"
# greeter.py def greet(name): print(f"Merhaba, {name}!") print(f"__name__ = {__name__}") if __name__ == "__main__": print("Doğrudan çalıştırılıyor") greet("Dünya")
$ python greeter.py __name__ = __main__ Doğrudan çalıştırılıyor Merhaba, Dünya!
# main.py import greeter
$ python main.py __name__ = greeter
Görüyorsun — import edildiğinde bloğu çalışmıyor. Bu ne işine yarıyor?
if __name__ == "__main__":İşine yarayan senaryo: Modülünü hem import-edilebilir hem direkt-çalıştırılabilir yapmak.
# calculator.py def add(a, b): return a + b def multiply(a, b): return a * b # Bu satırlar sadece doğrudan çalıştırınca işler if __name__ == "__main__": print("Test:") print(f"2 + 3 = {add(2, 3)}") print(f"4 * 5 = {multiply(4, 5)}")
Şimdi test çıktısı verir. Ama ile başka dosyada kullanırken test çıktıları gösterilmez.
python calculator.pyfrom calculator import addBu pattern Python'da o kadar yaygın ki hemen her ciddi script'te göreceksin. Senin yazdığın script'lere de eklemen tavsiye edilir.
python -m flag'i — modül olarak çalıştırma#
python -mpython script.pypython -m script# Yöntem 1: dosya yolu olarak python /path/to/script.py # Yöntem 2: modül adı olarak python -m script
-m1. Standard kütüphane modüllerini doğrudan çağırma#
# HTTP server (standart kütüphanede gelir) python -m http.server 8000 # Şimdi http://localhost:8000 ile mevcut klasörü serve # JSON validate / format python -m json.tool < data.json # Pip kendisi bir modül python -m pip install requests # Venv yarat python -m venv myenv # Cprofile ile profile et python -m cProfile -s cumulative myscript.py # Test runner python -m unittest # Compile python -m py_compile myscript.py
2. Paket içinde main entry point#
Bir paketin ( olan klasör) içinde dosyası olduğunda:
__init__.py__main__.pymypackage/ ├── __init__.py ├── __main__.py # python -m mypackage çağrılınca bu çalışır └── core.py
# mypackage/__main__.py from mypackage.core import run if __name__ == "__main__": run()
python -m mypackage
Bu pattern modern Python projelerinde standart. ettiğin paketler de bu yaklaşımla CLI'larını sağlıyor.
pip install3. pip'i her zaman python -m pip ile çağır#
python -m pipBu önerimi çok ciddiye al:
# Kötü pip install paket # İyi python -m pip install paket
Neden? global PATH'te olabilir; hangi Python'a kurduğunu bilmezsin (özellikle birden fazla Python varsa). her zaman mevcut python'a kurar — kafa karışıklığı yok.
pippython -m pipKomut satırı argümanları — sys.argv#
sys.argvScript'in komut satırından gelen argümanları okuyabilir:
# greet.py import sys print(f"Toplam argüman sayısı: {len(sys.argv)}") print(f"Argüman listesi: {sys.argv}") if len(sys.argv) < 2: print("Kullanım: python greet.py <isim>") sys.exit(1) name = sys.argv[1] print(f"Merhaba, {name}!")
$ python greet.py Toplam argüman sayısı: 1 Argüman listesi: ['greet.py'] Kullanım: python greet.py <isim> $ python greet.py Şükrü Toplam argüman sayısı: 2 Argüman listesi: ['greet.py', 'Şükrü'] Merhaba, Şükrü! $ python greet.py Şükrü Yusuf Toplam argüman sayısı: 3 Argüman listesi: ['greet.py', 'Şükrü', 'Yusuf'] Merhaba, Şükrü!
sys.argv[0]sys.argv[1:]sys.exit() ve exit code#
sys.exit()sys.exit(0) # başarılı sys.exit(1) # hata sys.exit("Hata mesajı") # mesaj stderr'e yazıp 1 ile çıkar
Shell script'lerinden Python script'i çağırırken exit code önemli — başarılı/başarısız ayrımını shell yapıyor:
python greet.py Şükrü && echo "Başardı" || echo "Başarısız"
argparse — büyük script'ler için#
sys.argvargparseimport argparse parser = argparse.ArgumentParser(description="Greet someone") parser.add_argument("name", help="İsim") parser.add_argument("--lang", default="tr", choices=["tr", "en"], help="Dil") parser.add_argument("--upper", action="store_true", help="Büyük harf") args = parser.parse_args() greeting = "Hello" if args.lang == "en" else "Merhaba" message = f"{greeting}, {args.name}!" if args.upper: message = message.upper() print(message)
$ python greet.py Şükrü --lang en --upper HELLO, ŞÜKRÜ! $ python greet.py --help usage: greet.py [-h] [--lang {tr,en}] [--upper] name Greet someone positional arguments: name İsim optional arguments: -h, --help show this help message and exit --lang {tr,en} Dil --upper Büyük harf
argparse otomatik üretir, validation yapar, type conversion. CLI yazacaksan yerine bunu kullan.
--helpsys.argv__pycache__ ve .pyc dosyaları#
__pycache__Bir Python dosyasını import ettiğinde Python onu bytecode'a derler ve cache'ler. Sonraki çalıştırmada bu cache'i kullanır — daha hızlı.
$ ls -la hello.py $ python -c "import hello" $ ls -la hello.py __pycache__/ hello.cpython-313.pyc
__pycache__- — Python 3.13 için bytecode.
hello.cpython-313.pyc
Birden fazla Python sürümünde aynı dosyayı kullanırsan ve gibi farklı cache'ler oluşur.
hello.cpython-310.pychello.cpython-313.pyc.pyc dosyaları nedir?#
CPython, kaynak kodu doğrudan çalıştırmaz; önce bytecode'a derler:
# Bytecode'u görmek için import dis def add(a, b): return a + b dis.dis(add)
2 0 LOAD_FAST 0 (a) 2 LOAD_FAST 1 (b) 4 BINARY_ADD 6 RETURN_VALUE
Bu bytecode 'de saklanıyor. Bir sonraki import'ta direkt bytecode'tan çalıştırır — kaynak kodu tekrar parse etmez.
.pyc__pycache__ git'e koymalı mıyım?#
__pycache__Hayır. 'a ekle:
.gitignore# .gitignore __pycache__/ *.pyc *.pyo *.pyd
Cache dosyaları Python sürümüne özel; başkasının makinesinde çalışmayabilir. Her makine kendi cache'ini üretir.
Cache'i devre dışı bırakmak#
# Bytecode cache'ini yazma python -B script.py # Veya environment variable export PYTHONDONTWRITEBYTECODE=1
Bunu sadece özel durumlarda yapman gerekir; default cache iyi.
stdin, stdout, stderr — UNIX dünyasıyla buluşma#
Python script'leri Unix-style I/O'yu doğal kullanır:
- stdin: Standart girdi (klavye veya pipe)
- stdout: Standart çıktı (terminal veya pipe)
- stderr: Standart hata (terminal veya pipe, ayrı)
import sys # stdout (default print buraya yazar) print("Bu stdout'a") sys.stdout.write("Bu da stdout'a\n") # stderr (uyarı, hata, log için) print("Bu stderr'e", file=sys.stderr) sys.stderr.write("Bu da stderr'e\n") # stdin data = sys.stdin.read() print(f"Stdin'den {len(data)} karakter okudum") # Satır satır for line in sys.stdin: print(f"Aldım: {line.strip()}")
Pipe örnekleri#
# stdin'den oku echo "Merhaba" | python script.py # stdout'u dosyaya yönlendir python script.py > output.txt # stderr'i ayır python script.py 2> errors.txt # İkisini birden ama ayrı python script.py > output.txt 2> errors.txt # stdout + stderr aynı yere python script.py > combined.txt 2>&1 # stderr'i discard python script.py 2> /dev/null
Profesyonel script'ler:
- Bilgi mesajları: stderr'e (logging modülü)
- Asıl veri çıktısı: stdout'a (machine-readable, pipe edilebilir)
import sys import logging logging.basicConfig(stream=sys.stderr, level=logging.INFO) logging.info("İşlem başladı") # → stderr print("output_data") # → stdout
Bu sayede başkası senin script'inin output'unu pipe edebilir, log mesajları karışmaz.
Pratik script'ler — gerçek örnekler#
Modül 1'in kapanışında 4 küçük gerçek script ile pratik yap.
Script 1: Çevre değişkeni okuyan basit util#
#!/usr/bin/env python3 """Çevre değişkenini güvenli şekilde okuyup yazdırır.""" import os import sys def main(): if len(sys.argv) != 2: print("Kullanım: getenv.py <DEĞİŞKEN_ADI>", file=sys.stderr) sys.exit(1) var_name = sys.argv[1] value = os.environ.get(var_name) if value is None: print(f"'{var_name}' tanımlı değil.", file=sys.stderr) sys.exit(2) print(value) sys.exit(0) if __name__ == "__main__": main()
$ python getenv.py HOME /Users/me $ python getenv.py NOT_EXISTS 'NOT_EXISTS' tanımlı değil.
Script 2: Klasördeki dosyaları sayan + tipe göre gruplayan#
#!/usr/bin/env python3 """Verilen klasördeki dosyaları uzantıya göre grupla ve say.""" import os import sys from collections import Counter from pathlib import Path def main(): folder = sys.argv[1] if len(sys.argv) > 1 else "." path = Path(folder) if not path.is_dir(): print(f"Klasör bulunamadı: {folder}", file=sys.stderr) sys.exit(1) counter = Counter() total_size = 0 for file in path.rglob("*"): if file.is_file(): ext = file.suffix.lower() or "(no extension)" counter[ext] += 1 total_size += file.stat().st_size print(f"Klasör: {path.absolute()}") print(f"Toplam dosya: {sum(counter.values())}") print(f"Toplam boyut: {total_size / 1024 / 1024:.2f} MB") print() print("Uzantıya göre dağılım:") for ext, count in counter.most_common(20): print(f" {ext:20s}: {count:5d}") if __name__ == "__main__": main()
$ python file_stats.py ~/Downloads Klasör: /Users/me/Downloads Toplam dosya: 142 Toplam boyut: 256.34 MB Uzantıya göre dağılım: .pdf : 34 .png : 27 .zip : 18 ...
Script 3: HTTP fetch + JSON parse#
#!/usr/bin/env python3 """GitHub kullanıcı bilgilerini API'den çek.""" import json import sys import urllib.request import urllib.error def main(): if len(sys.argv) != 2: print("Kullanım: github_user.py <username>", file=sys.stderr) sys.exit(1) username = sys.argv[1] url = f"https://api.github.com/users/{username}" try: with urllib.request.urlopen(url, timeout=10) as response: data = json.load(response) except urllib.error.HTTPError as e: print(f"HTTP hata: {e.code} {e.reason}", file=sys.stderr) sys.exit(2) except urllib.error.URLError as e: print(f"Network hata: {e.reason}", file=sys.stderr) sys.exit(3) print(f"Kullanıcı: {data['login']}") print(f"İsim: {data.get('name', '(belirtilmemiş)')}") print(f"Şirket: {data.get('company', '(belirtilmemiş)')}") print(f"Bio: {data.get('bio', '(belirtilmemiş)')}") print(f"Repo: {data['public_repos']}") print(f"Takipçi: {data['followers']}") print(f"Takip: {data['following']}") print(f"Profil: {data['html_url']}") if __name__ == "__main__": main()
$ python github_user.py torvalds Kullanıcı: torvalds İsim: Linus Torvalds Şirket: Linux Foundation Bio: (belirtilmemiş) Repo: 8 Takipçi: 245789 Takip: 0 Profil: https://github.com/torvalds
Script 4: Mini CLI — hesap makinesi#
#!/usr/bin/env python3 """Komut satırı hesap makinesi.""" import argparse import sys def main(): parser = argparse.ArgumentParser(description="Basit hesap makinesi") parser.add_argument("a", type=float, help="İlk sayı") parser.add_argument("op", choices=["+", "-", "*", "/", "**", "%"], help="Operatör") parser.add_argument("b", type=float, help="İkinci sayı") parser.add_argument("--precision", type=int, default=4, help="Ondalık hassasiyet (default 4)") args = parser.parse_args() operations = { "+": lambda a, b: a + b, "-": lambda a, b: a - b, "*": lambda a, b: a * b, "/": lambda a, b: a / b if b != 0 else float("nan"), "**": lambda a, b: a ** b, "%": lambda a, b: a % b if b != 0 else float("nan"), } result = operations[args.op](args.a, args.b) print(f"{args.a} {args.op} {args.b} = {result:.{args.precision}f}") if __name__ == "__main__": main()
$ python calc.py 10 + 5 10.0 + 5.0 = 15.0000 $ python calc.py 7 / 3 --precision 2 7.0 / 3.0 = 2.33 $ python calc.py 2 ** 10 2.0 ** 10.0 = 1024.0000 $ python calc.py 5 + a calc.py: error: argument b: invalid float value: 'a'
Bu 4 script kombinasyonunda modül 1'de öğrendiklerinin pratik kullanımı var: shebang, encoding (otomatik), , sys.argv, sys.exit, argparse, stderr, exit code, modül kullanımı.
__name__ == "__main__"Şimdi bu script'leri kendi makinende çalıştır. Modify et, oynat. Bu egzersiz Modül 1'in capstone'u.
"Python yorumlanan dil" derken — pratikte ne demek?#
Aslında saf yorumlanan değil, hibrit. Çalışma akışı:
- Source code () →
hello.py - Lexer/Parser: Token'lara böl, AST (Abstract Syntax Tree) yarat →
- Compile: AST'ten bytecode üret () →
.pyc - Bytecode VM: Python'un içsel yorumlayıcısı bytecode'u çalıştırır.
import dis def hello(): print("Hi") dis.dis(hello)
2 0 LOAD_GLOBAL 0 (print) 2 LOAD_CONST 1 ('Hi') 4 CALL_FUNCTION 1 6 POP_TOP 8 LOAD_CONST 0 (None) 10 RETURN_VALUE
Bu bytecode'u Python VM çalıştırır. CPython'un kalbi.
Bu detayı bilmek günlük programcılık için gerekmez ama:
- "Python neden Java'dan yavaş?" sorusuna cevap (Java JIT'leniyor; CPython sadece bytecode-interpret).
- PyPy ne yapıyor? Bytecode'u JIT ile makine koduna çeviriyor.
- Cython ne yapıyor? Python'u doğrudan C'ye çeviriyor.
Bu cümleler artık daha anlamlı.
Modül 1 sonu — neler kazandın?#
✓ İlk Python script'in: ve ile çalıştırma.
hello.pypython✓ Shebang line () ve ile executable yapma.
#!/usr/bin/env python3chmod +x✓ Encoding declaration tarihi — Python 3'te artık gerek yok.
✓ deyiminin anlamı ve neden her ciddi script'te olduğu.
__name__ == "__main__"✓ flag'i — modül olarak çalıştırma, http.server, json.tool, pip, venv gibi standart kullanımları.
python -m✓ ile komut satırı argümanları, ve exit code'lar.
sys.argvsys.exit✓ ile profesyonel CLI yapısı.
argparse✓ ve dosyaları — bytecode cache.
__pycache__.pyc✓ stdin/stdout/stderr — UNIX I/O ile uyum.
✓ 4 gerçek hands-on script ile tüm bu kavramları birlikte gördün.
✓ CPython internals — kaynak kod → AST → bytecode → VM, Python'un kalp atışı.
Modül 1 capstone — kendine sor:#
Aşağıdaki sorulara verebileceğin cevaplar yoksa, ilgili dersi tekrar oku. Verebiliyorsan — Modül 2'ye hazırsın!
- CPython, PyPy, MicroPython, Pyodide arasındaki fark nedir? (Ders 3)
- Python 2 ile 3 arasındaki büyük ayrılık ne hakkındaydı? (Ders 2)
- Pythonic kod nedir, nasıl tanırsın? (Ders 4)
- Birden fazla Python sürümünü makinende nasıl yönetirsin? (Ders 7-8)
- REPL'de ve
?farkı nedir? (Ders 9-10)?? - Jupyter Notebook'un git ile çalışmasında ne gibi sorunlar olur? (Ders 11)
- VS Code'da virtualenv'i nasıl seçip aktif edersin? (Ders 12)
- PyCharm Pro'da Community'de olmayan ne var? (Ders 13)
- neden yazılır? (Ders 14)
if __name__ == "__main__": - neden
python -m pipdirekt çağırmaktan iyidir? (Ders 14)pip
10/10 alıyorsan, Modül 1 ara quizi'ne girebilirsin → /learn/quiz/python-module-1-quiz
Sonraki adım#
Modül 2: Veri Tipleri ve Operatörler'le devam edeceğiz. Değişkenler, sayısal tipler (int/float/decimal/fractions), boolean ve None, operatörler (mantıksal/karşılaştırma/bit-level), type conversion, identity vs equality ( vs )... 15 ders boyunca Python'un veri katmanını derinlemesine kazıyacağız.
is==Görüşmek üzere — gerçek programlama burada başlıyor. ☕
Sık Sorulan Sorular
Modern dünyada `python3` daha taşınabilir. Ama eğer pyenv kullanıyorsan ve `pyenv global 3.13.0` ile default ayarladıysan, `python` da çalışıyor (pyenv shim'leri sayesinde). Pratik tavsiye: profesyonel script'lerde `python3` veya `python3.13` (sürüm spesifik), kişisel REPL'inde `python` (kısa yazmak için).
Yorumlar & Soru-Cevap
(0)Yorum yazmak için giriş yap.
Yorumlar yükleniyor...
İlgili İçerikler
Modül 1: Giriş ve Kurulum
Python Nedir, Neden Bu Kadar Popüler?
Öğrenmeye BaşlaModül 1: Giriş ve Kurulum
Python Sürümlerinin Tarihi: 2'den 3.14'e, AI Winter'lardan 'No-GIL' Devrimine
Öğrenmeye BaşlaModül 1: Giriş ve Kurulum