# CPython, Bytecode ve Python Virtual Machine (PVM)

> Source: <https://dev.to/vebendeakademi/cpython-bytecode-ve-python-virtual-machine-pvm-da9>
> Published: 2026-06-15 05:19:52+00:00

Python öğrenen çoğu geliştirici şu aşamaya kadar gelir:

```
x = 10
y = 20
print(x + y)
```

Kod çalışır, sonuç gelir ve konu kapanır.

Fakat profesyonel seviyede Python geliştiren, performans optimizasyonu yapan veya Python'un iç mimarisini anlamak isteyen bir yazılımcının aşağıdaki üç kavramı çok iyi bilmesi gerekir:

Bu üçü Python'un çalışma motorunu oluşturur.

Bir Python programı çalıştırıldığında süreç şu şekildedir:

```
Python Source Code
        ↓
Tokenizer
        ↓
Parser
        ↓
AST
        ↓
Compiler
        ↓
Bytecode
        ↓
Python Virtual Machine
        ↓
CPython Runtime
        ↓
Operating System
        ↓
CPU
```

Buradaki en kritik bölüm:

```
Bytecode
    ↓
PVM
```

çiftidir.

Öncelikle çok önemli bir yanlış anlaşılmayı düzeltelim.

Birçok kişi Python'u bir dil zanneder.

Aslında:

```
Python = Dil Spesifikasyonu
```

CPython ise:

```
Python'un en yaygın implementasyonu
```

dur.

Nasıl ki:

```
C#
Java
JavaScript
```

bir dil tanımıysa,

Python da bir dil tanımıdır.

Bu tanımı çalıştıran farklı motorlar vardır.

Örneğin:

| Implementasyon | Dil |
|---|---|
| CPython | Python |
| PyPy | Python |
| Jython | Python |
| IronPython | Python |
| MicroPython | Python |

Hepsi Python kodu çalıştırır.

Ama iç yapıları farklıdır.

CPython:

```
C dili ile yazılmış Python yorumlayıcısıdır.
```

Python.org üzerinden indirdiğiniz standart Python budur.

Örneğin:

```
python app.py
```

komutu verdiğinizde çalışan şey CPython'dur.

CPython'ın kaynak kodu yaklaşık:

```
500.000+ satır C
```

içerir.

Kaynak kodu:

CPython:

```
x = 10
y = 20
print(x + y)
```

kodunu alır.

Sonra:

```
Token
↓
AST
↓
Bytecode
↓
PVM Execution
```

işlemlerini gerçekleştirir.

Basitleştirilmiş görünüm:

```
CPython
│
├── Lexer
├── Parser
├── Compiler
├── Bytecode Generator
├── PVM
├── Garbage Collector
├── Memory Manager
└── C API
```

Python doğrudan makine koduna çevrilmez.

Java'da olduğu gibi ara bir temsil oluşturulur.

Buna:

```
Bytecode
```

denir.

Kodumuz:

```
x = 10
y = 20
z = x + y
```

olsun.

Python bunu aşağıdakine benzer bytecode'a dönüştürür:

```
LOAD_CONST 10
STORE_NAME x

LOAD_CONST 20
STORE_NAME y

LOAD_NAME x
LOAD_NAME y

BINARY_ADD

STORE_NAME z
```

Python'un şu kodu:

```
x + y
```

işlemciye doğrudan gönderilemez.

Çünkü CPU şunu anlamaz:

```
x
+
y
```

Bu nedenle Python önce bunu standart komutlara dönüştürür.

Python'da:

``` python
import dis

def test():
    x = 10
    y = 20
    return x + y

dis.dis(test)
```

çıktı:

```
LOAD_CONST 10
STORE_FAST x

LOAD_CONST 20
STORE_FAST y

LOAD_FAST x
LOAD_FAST y

BINARY_OP +
RETURN_VALUE
```

şeklinde olur.

Python bytecode'u diske de yazabilir.

Örneğin:

```
main.py
```

çalıştırıldığında:

```
__pycache__
```

oluşur.

İçinde:

```
main.cpython-313.pyc
```

benzeri dosyalar vardır.

Bu dosya:

```
Bytecode
```

saklar.

Tekrar derleme maliyetini azaltmak için.

İkinci çalıştırmada:

```
.py
```

yerine

```
.pyc
```

kullanılabilir.

Bu da açılış süresini azaltır.

Hayır.

En çok karıştırılan konu budur.

Bytecode:

```
LOAD_FAST
STORE_FAST
BINARY_ADD
```

gibi komutlardan oluşur.

CPU bunları anlayamaz.

Bu komutları çalıştıracak başka bir sistem gerekir.

İşte burada PVM devreye girer.

PVM:

```
Python Bytecode'unu çalıştıran sanal işlemcidir.
```

Gerçek CPU:

```
MOV
ADD
SUB
MUL
```

gibi komutlar çalıştırır.

PVM ise:

```
LOAD_FAST
STORE_FAST
CALL_FUNCTION
BINARY_ADD
```

çalıştırır.

Bytecode:

```
LOAD_FAST x
LOAD_FAST y
BINARY_ADD
```

üretmiştir.

PVM bunu okur.

```
LOAD_FAST x
```

çalışır.

Stack:

```
10
LOAD_FAST y
```

çalışır.

Stack:

```
20
10
BINARY_ADD
```

çalışır.

Stack:

```
30
```

Bu nedenle PVM'e bazen:

```
Stack Based Virtual Machine
```

denir.

Örnek:

```
3 + 5
```

Bytecode:

```
LOAD_CONST 3
LOAD_CONST 5
BINARY_ADD
```

PVM:

```
PUSH 3
PUSH 5
ADD
```

mantığıyla çalışır.

Aslında PVM ayrı bir program değildir.

CPython'ın içindedir.

Şöyle düşünün:

```
CPython
│
├── Compiler
├── Bytecode
└── PVM
```

Yani:

```
PVM ⊂ CPython
```

Örneğin:

```
x = 10
```

gördüğümüzde:

"10" doğrudan RAM'e yazılmaz.

CPython şu yapıyı oluşturur:

```
PyLongObject
```

Basitleştirilmiş hali:

```
struct {
    reference_count;
    type;
    value;
}
```

Yani:

```
10
```

aslında bir nesnedir.

PVM:

```
BINARY_ADD
```

gördüğünde:

CPython içindeki C fonksiyonlarını çağırır.

Örneğin:

```
PyNumber_Add()
```

Bu fonksiyon:

```
10 + 20
```

mi?

```
"abc" + "def"
```

mi?

```
list1 + list2
```

mi?

kontrol eder.

Sonra uygun işlemi gerçekleştirir.

CPython içinde.

Örneğin:

```
x = [1,2,3]
```

oluşturuldu.

Daha sonra:

```
x = None
```

oldu.

Referans kalmadığında:

```
Reference Counting
```

ve

```
Garbage Collector
```

mekanizmaları belleği temizler.

Python'un C veya Rust'tan yavaş olmasının temel nedeni budur.

Çünkü:

```
x + y
```

ifadesi:

gibi birçok katmandan geçer.

C dilinde ise:

```
int z = x + y;
```

doğrudan makine koduna çevrilir.

Bütün sistemi tek diyagramda özetlersek:

```
Python Source Code
        │
        ▼
   CPython Parser
        │
        ▼
      AST
        │
        ▼
    Compiler
        │
        ▼
    Bytecode
        │
        ▼
Python Virtual Machine
        │
        ▼
 CPython Runtime (C)
        │
        ▼
 Operating System
        │
        ▼
      CPU
        │
        ▼
   Machine Code
```

Özetle:

Bu üç yapıyı anladığınızda Python artık yalnızca bir programlama dili değil; derleyici teorisi, sanal makineler, işletim sistemleri ve bilgisayar mimarisinin kesişim noktasında çalışan çok katmanlı bir yürütme platformu olarak görünmeye başlar.
