İçeriğe geç

Menü

Berk Akademi
Yorumlar Google yorumları Birebir ders başvurusu Ücretsiz ön görüşme Ana Sayfa

Python JSON Türkçe Karakter Sorunu Nasıl Çözülür? ensure_ascii

python-json-turkce-karakter-sorunu-ensure-ascii
Bu yazıda neler var?
  1. JSON'da Türkçe harfler neden u kaçışı olarak görünür?
  2. json.dumps ile json.dump arasındaki fark nedir?
  3. Dosyaya yazarken encoding belirtmezsen ne olur?
  4. Uygulamalı örnek: aynı sözlüğü iki biçimde yaz, oku ve == ile karşılaştır
  5. Hâlâ bozuk görünüyorsa: kontrol listesi
  6. Sık Sorulan Sorular

Python JSON Türkçe karakter sorunu çoğu zaman gerçek bir bozulma değil, varsayılan davranışın sonucudur: json.dumps ve json.dump varsayılan ayarla ASCII dışındaki harfleri u0130 gibi kaçış dizilerine çevirir. Okunabilir çıktı için ensure_ascii=False verirsin; dosyaya yazıyorsan dosyayı encoding="utf-8" ile açarsın. Bu iki ayar farklı katmanlara aittir ve sorunu doğru çözmek için bu katmanları ayırmak gerekir.

JSON'da Türkçe harfler neden u kaçışı olarak görünür?

Türkçe karakterlerle çalışırken aynı veri üç ayrı katmandan geçer:

  1. Python string değeri: Bellekte "İzmir" gerçek Türkçe karakterle durur. Burada hiçbir kaçış yoktur.
  2. JSON gösterimi: Aynı karakter JSON metninde ya olduğu gibi ya da uXXXX kaçışıyla yazılabilir. İkisi de geçerli JSON'dur.
  3. Dosya kodlaması: Metnin diske hangi baytlarla yazılacağını belirler. UTF-8 bunlardan biridir.

Karışıklık, birinci ve ikinci katmanın aynı şey sanılmasından çıkar. Python'daki json modülünün ensure_ascii parametresi ikinci katmanı yönetir. python.org dokümantasyonuna göre parametre True iken (varsayılan budur) çıktıda ASCII dışındaki bütün karakterler kaçışlı yazılır; False iken bu karakterler olduğu gibi çıktıya konur. Yani varsayılan davranış, çıktının yalnızca ASCII karakterlerden oluşmasını sağlar.

Aynı sözlüğü iki ayarla yazdıralım:

import json

veri = {"sehir": "İzmir"}
print(json.dumps(veri))
print(json.dumps(veri, ensure_ascii=False))

Beklenen çıktı:

{"sehir": "u0130zmir"}
{"sehir": "İzmir"}

Büyük harf İ'nin Unicode kod noktası U+0130'dur; birinci satırdaki u0130 bu karakterin yazılış biçimidir. JSON içindeki u kaçışları veri kaybı anlamına gelmez, gösterim biçimidir. Kaçışlı metni json.loads ile geri okursan yine "İzmir" elde edersin. Kaçışlı çıktıyı bozuk saymak yerine, o metni insan gözüyle okumak istiyor musun diye düşünmek daha doğru bir başlangıçtır.

json.dumps ile json.dump arasındaki fark nedir?

json.dumps ile json.dump arasındaki fark nedir?

Fark, sonucun nereye gittiğindedir. json.dumps JSON metnini bir str olarak döndürür. Ekrana yazdırmak, bir değişkende tutmak ya da ağ üzerinden göndermek istediğinde bunu kullanırsın. json.dump ise aynı dönüşümü yapar ama sonucu geri döndürmek yerine açık bir dosya nesnesine yazar.

import json

veri = {"sehir": "İzmir"}
metin = json.dumps(veri, ensure_ascii=False)
print(type(metin))

Beklenen çıktı:

<class 'str'>

Dosyaya yazan karşılığın iskeleti şöyledir:

with open("veri.json", "w", encoding="utf-8") as dosya:
    json.dump(veri, dosya, ensure_ascii=False)

İki fonksiyon da ensure_ascii parametresini aynı biçimde alır; yani kaçış kararını her ikisinde de sen verirsin. Ancak json.dump bir dosyaya yazdığı için üçüncü katman devreye girer: open çağrısındaki encoding değeri, o metnin diskte hangi baytlara dönüşeceğini belirler. Sıradaki bölümde bu parametreyi yazmazsan ne olacağına bakacağız.

Dosyaya yazarken encoding belirtmezsen ne olur?

Dosyaya yazarken encoding belirtmezsen ne olur?

ensure_ascii=False yazdığında JSON metni gerçek Türkçe harflerle (ş, ı, ğ, ü, ö, ç) oluşur. Bu harflerin dosyada hangi baytlarla saklanacağını ise JSON değil, open() fonksiyonunun encoding parametresi belirler. Bu üçüncü katmandır: Python string'i bellekte harflerden oluşur, JSON onların metin gösterimidir, dosya kodlaması da metnin diskteki bayt karşılığıdır.

Python'un resmî dokümantasyonuna göre encoding verilmezse kullanılan kodlama platforma bağlıdır; yani bilgisayarın yerel ayarı belirler. Aynı kod bir bilgisayarda sorunsuz çalışırken başkasında Türkçe karakterleri bozuk yazabilir ya da UnicodeEncodeError verebilir. Dokümantasyon, metin dosyalarında kodlamayı açıkça belirtmeyi önerir.

Varsayılan ensure_ascii=True ile bu sorun çoğu zaman fark edilmez. Çünkü çıktı yalnızca ASCII karakterlerden oluşur ve ASCII karakterler yaygın kodlamalarda aynı baytlara karşılık gelir. ensure_ascii=False'a geçtiğinde ise kodlama seçimi sonucu doğrudan etkiler.

# Riskli: encoding yok, kodlamayı ortam seçer
with open("veri.json", "w") as f:
    json.dump(veri, f, ensure_ascii=False)

# Güvenli: kodlama açıkça belirtilmiş
with open("veri.json", "w", encoding="utf-8") as f:
    json.dump(veri, f, ensure_ascii=False)

İlk blok, kodun hangi bilgisayarda çalıştığına bağlı olarak farklı sonuç verebilir. İkinci blok her yerde aynı baytları üretir. Okurken de aynı kuralı uygula: open("veri.json", "r", encoding="utf-8"). Yazarken ve okurken encoding="utf-8" yazmayı alışkanlık hâline getirirsen kodun başka bir bilgisayarda da aynı davranır. Bu alışkanlığı birebir Python dersleri kapsamında dosya işlemlerini öğrenirken de kazanabilirsin.

Uygulamalı örnek: aynı sözlüğü iki biçimde yaz, oku ve == ile karşılaştır

Aşağıdaki program tek bir sözlüğü iki dosyaya yazar: biri varsayılan ensure_ascii ile, biri ensure_ascii=False ile. İkisi de encoding="utf-8" ile açılır. Sonra dosyalar önce ham metin olarak okunur, ardından json.load ile Python verisine dönüştürülür.

import json

veri = {
    "ogrenci": "Işıl Öztürk",
    "sehir": "Gümüşhane",
    "ders": "Değişkenler ve Döngüler"
}

with open("kacisli.json", "w", encoding="utf-8") as f:
    json.dump(veri, f)

with open("duz.json", "w", encoding="utf-8") as f:
    json.dump(veri, f, ensure_ascii=False)

for ad in ("kacisli.json", "duz.json"):
    with open(ad, "r", encoding="utf-8") as f:
        print(f.read())

with open("kacisli.json", "r", encoding="utf-8") as f:
    a = json.load(f)
with open("duz.json", "r", encoding="utf-8") as f:
    b = json.load(f)

print(a == b, a == veri)

Beklenen çıktı:

{"ogrenci": "Iu015fu0131l u00d6ztu00fcrk", "sehir": "Gu00fcmu00fcu015fhane", "ders": "Deu011fiu015fkenler ve Du00f6ngu00fcler"}
{"ogrenci": "Işıl Öztürk", "sehir": "Gümüşhane", "ders": "Değişkenler ve Döngüler"}
True True

İki dosyanın ham içeriği yan yana şöyle görünür:

ensure_ascii varsayılanensure_ascii=False
"ogrenci": "Iu015fu0131l u00d6ztu00fcrk""ogrenci": "Işıl Öztürk"
"sehir": "Gu00fcmu00fcu015fhane""sehir": "Gümüşhane"

json.load, uXXXX kaçışlarını otomatik olarak gerçek karaktere çevirir. Bu yüzden a == b ve a == veri ifadelerinin ikisi de True verir. Kaçışlı dosya da kaçışsız dosya da json.load ile aynı Python verisini verir; fark yalnızca dosyanın göze nasıl göründüğündedir.

Hâlâ bozuk görünüyorsa: kontrol listesi

Türkçe karakterler hâlâ yanlış görünüyorsa sorunu tek seferde değil, katman katman ara. Aşağıdaki sıra, en sık rastlanan nedenden en az rastlanana doğru ilerler.

  1. Yazarken: json.dump ya da json.dumps çağrısında ensure_ascii=False var mı? Yoksa ş ve ğ gibi harfler u015f, u011f biçiminde yazılır.
  2. Dosya kodlaması: Dosya hem yazılırken hem okunurken open(..., encoding="utf-8") ile açıldı mı? open kodlama verilmezse sistemin yerel ayarına bağlı bir varsayılan kullanır, bu yüzden aynı kod farklı bilgisayarlarda farklı davranabilir.
  3. Görüntüleyici: Dosyayı açan editör ya da görüntüleyici içeriği UTF-8 olarak mı yorumluyor? Dosya doğru yazılmış olsa bile yanlış kodlamayla açılırsa harfler bozuk görünür.
  4. Sorunun yeri: Bozukluk dosyada mı, yoksa yalnızca terminal ya da konsol çıktısında mı? Dosyayı json.load ile geri okuyup orijinal sözlükle == karşılaştır. Sonuç True ise veri sağlam demektir.
  5. Alıcı taraf: JSON'u başka bir programa ya da servise gönderiyorsan alıcının UTF-8 beklediğinden emin ol.

Dördüncü madde önemlidir, çünkü konsolun kodlaması ile dosyanın kodlaması ayrı konulardır. print ile ekrana yazılan metin, konsolun kullandığı kodlamaya göre gösterilir; dosyaya yazılan metin ise open ile belirlediğin kodlamayla saklanır. Konsolda bozuk görünen bir çıktı, verinin bozulduğu anlamına gelmeyebilir. Önce dosyayı geri okuyarak sorunu ayır, sonra yalnızca ilgili katmanı düzelt.

Bu adımlar sonunda Python'daki string, dosya ve kodlama kavramlarında takıldığın yeri görmek istersen ücretsiz Python bilgi testiyle seviyeni ölçebilirsin.

Sık Sorulan Sorular

ensure_ascii=False kullanırken UnicodeEncodeError alıyorum, neden?

Bu hata genellikle metnin, hedefin desteklemediği bir kodlamayla yazılmaya çalışıldığını gösterir. Dosyaya yazıyorsan open çağrısına encoding="utf-8" ekle. Hata print sırasında çıkıyorsa sorun konsolun kodlamasındadır, JSON'da değil.

json.load ile kaçışlı dosyayı okurken ayrıca bir ayar yapmam gerekir mi?

Kaçış dizilerini ayrıştırıcı kendisi çözer, bunun için ek bir parametre gerekmez. Yapman gereken tek şey dosyayı doğru kodlamayla, yani encoding="utf-8" ile açmaktır.

ensure_ascii varsayılan kalırsa Türkçe veri bozulur mu?

Bozulmaz. JSON içindeki u kaçışları veri kaybı anlamına gelmez, gösterim biçimidir. Dosyayı okuyunca aynı karakterler geri gelir; yalnızca dosyayı gözle okumak zorlaşır.

Türkçe karakter sorununu çözerken üç katmanı ayrı düşün: Python'daki string, JSON gösterimi ve dosya kodlaması. Hangi katmanda takıldığını bulduğunda çözüm çoğunlukla tek bir parametreye iner.

Bu içerik aradığın cevabı verdi mi?
Yanıtın, hangi yazıları geliştirmemiz gerektiğini anlamamıza yardımcı olur.
Bu içeriğin üretilmesinde yapay zeka araçlarından destek alınmıştır.

Bu konudan sonra ne okuyabilirsin?

Tüm yazılar

İlgili Eğitimler

Berk Keskin, yazılım geliştirici ve eğitmen
Yazar

Berk Keskin Kimdir?

Yazılıma 12 yaşında başladı; İzmir Ekonomi Üniversitesi'ni bölüm birincisi ve yüksek şeref öğrencisi olarak tamamladı. Bugün yalnızca eğitim vermekle kalmıyor, sektörde aktif olarak yazılım projeleri geliştiriyor ve gerçek dünya deneyimini birebir derslerine taşıyor. Ezberden uzak, mühendislik zihniyetini merkeze alan sürdürülebilir öğrenme sistemleri tasarlayarak sorgulayan, üreten ve problem çözebilen yeni nesil yazılımcılar yetiştiriyor.

Sektörel Deneyim & Projeler

  • Ticarify Entegrasyon Yazılım logosu CEO Ticarify Entegrasyon YazılımPazaryerleri ve e-ticaret sitelerine otomatik e-fatura kesimi, sipariş ve kargo takibi hizmetleri sunan e-Dönüşüm platformunun API mimarisini ve yazılım ekibini yönetmektedir.
  • Benim Düğünüm logosu CEO Benim DüğünümDijital etkinlik ve anı paylaşım platformu.
  • Siberdizayn logosu Yazılım Ekibi Lideri SiberdizaynYüksek anlık oyuncu trafiğine sahip oyun kontrol panelleri ve sunucu altyapıları geliştiren yazılım ekibine liderlik etmektedir.
  • MEDYOGRAFYA 360° Dijital Çözümler logosu Dijital Strateji Lideri MEDYOGRAFYA 360° Dijital ÇözümlerŞirketlerin dijital çözümlerde uzun vadede nasıl ilerlemesi gerektiği ve dijital dönüşüm süreçlerinin yönetilmesine destek olmaktadır.
  • İzmir Ekonomi Üniversitesi logosu Danışma Kurulu Üyesi İzmir Ekonomi ÜniversitesiMezun olduğu üniversitesinde, Bilgisayar Programcılığı bölümünün akademik müfredatını güncel sektör ihtiyaçlarına göre şekillendirmek adına Danışma Kurulu'nda görev almaktadır.
WhatsApp Hemen Ara