koddla

Yazılımcıları bilgi ile güçlendirir.

JSON Modülü

json modülü varsayılan olarak aşağıdaki türlerin kodlama (encoding) ve kod çözme (decoding) işlemlerini gerçekleştirir.

De-serialization türleri: 

JSONPython
nesnedict 
arraylist 
stringstr 
sayı (int)int 
sayı (real)float 
true, falseTrue, False 
nullNone 

json modülü ayrıca NaN, Infinity ve -Infinity değerlerini karşılık gelen float değerleri olarak anlar ki bu JSON spesifikasyonunun dışındadır.

Serialization türleri: 

PythonJSON
dictobject
list, tuplearray
strstring
int, floatnumber (int)
True, Falsetrue, false
Nonenull

NaN, Infinity ve -Infinity kodlamasına izin vermemek için allow_nan=False ile kodlamanız gerekir. Bu durumda, bu değerleri kodlamaya çalışırsanız bir ValueError oluşacaktır.

Özel deserialization-serialization 

Farklı şekilde temsil edilmesi gereken verileri işlemenize olanak tanıyan çeşitli kancalar vardır. functools.partial kullanımı, kolaylık sağlamak için ilgili parametreleri bu fonksiyonlara kısmen uygulamanıza olanak tanır.

Serialization: 

Nesneler serileştirilmeden önce nesneler üzerinde çalışan bir işlev sağlayabilirsiniz:

# my_json module

import json
from functools import partial

def serialise_object(obj):
    # Json serileştirilebilir veri üretmek için bir şeyler yapın
    return dict_obj

dump = partial(json.dump, default=serialise_object)
dumps = partial(json.dumps, default=serialise_object)

de-serialization: 

json fonksiyonları tarafından işlenen object_hook ve parse_float gibi çeşitli kancalar vardır. Python sürümünüz için kapsamlı bir liste için buraya bakın.

# my_json module

import json
from functools import partial

def deserialise_object(dict_obj):
    # Özel bir şey yap
    return obj

def deserialise_float(str_obj):
    # Özel bir şey yap
    return obj

load = partial(json.load, object_hook=deserialise_object, parse_float=deserialise_float)
loads = partial(json.loads, object_hook=deserialise_object, parse_float=deserialise_float)

Daha fazla özel deserialization-serialization 

json modülü ayrıca çeşitli türleri işlemek için json.JSONEncoder ve json.JSONDecoder’ın genişletilmesine/değiştirilmesine izin verir. Yukarıda belgelenen kancalar, eşdeğer şekilde adlandırılmış bir yöntem oluşturularak varsayılan olarak eklenebilir. Bunları kullanmak için ilgili fonksiyona cls parametresi olarak sınıfı geçirmeniz yeterlidir. functools.partial kullanımı, kolaylık sağlamak için cls parametresini bu fonksiyonlara kısmen uygulamanıza olanak tanır, örn.

# my_json module

import json
from functools import partial

class MyEncoder(json.JSONEncoder):
    # Özel bir şey yap

class MyDecoder(json.JSONDecoder):
    # Özel bir şey yap

dump = partial(json.dump, cls=MyEncoder)
dumps = partial(json.dumps, cls=MyEncoder)
load = partial(json.load, cls=MyDecoder)
loads = partial(json.loads, cls=MyDecoder)

Verilerin bir dosyada saklanması

Aşağıdaki kod parçacığı d’de saklanan verileri JSON’a kodlar ve bir dosyada saklar (dosya adını dosyanın gerçek adıyla değiştirin).

import json

d = {
    'foo': 'bar',
    'alice': 1,
    'wonderland': [1, 2, 3]
}

with open(dosyaadi, 'w') as f:
    json.dump(d, f)

Bir dosyadan veri alma

Aşağıdaki kod parçacığı JSON kodlu bir dosyayı açar (dosya adını dosyanın gerçek adıyla değiştirin) ve dosyada depolanan nesneyi döndürür.

import json

with open(dosyaadi, 'r') as f:
    d = json.load(f)

JSON çıktısını biçimlendirme

Diyelim ki elimizde aşağıdaki veriler var:

>>> data = {"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}

Bunu sadece JSON olarak dökmek burada özel bir şey yapmaz:

>>> print(json.dumps(data))
{"cats": [{"name": "Tubbs", "color": "white"}, {"name": "Pepper", "color": "black"}]}

Daha güzel çıktı almak için girintiyi ayarlama 

Eğer güzel bir çıktı istiyorsak, bir girinti boyutu ayarlayabiliriz:

>>> print(json.dumps(data, indent=2))
{
  "cats": [{
  "cats": [
		{
			“name”: “Tubbs”,
			“color”: “white”
		},
		{
			“name”: “Pepper”,
			“color”: “black”
		}
	]
}

Tutarlı çıktı elde etmek için anahtarları alfabetik olarak sıralama 

Varsayılan olarak çıktıdaki anahtarların sırası tanımsızdır. Her zaman aynı çıktıyı aldığımızdan emin olmak için bunları alfabetik sırayla alabiliriz:

>>> print(json.dumps(data, sort_keys=True))
{"cats": [{"color": "white", "name": "Tubbs"}, {"color": "black", "name": "Pepper"}]}

Kompakt çıktı elde etmek için boşluklardan kurtulma 

Gereksiz boşluklardan kurtulmak isteyebiliriz, bunu da varsayılan ‘, ‘ ve ‘: ‘ ayırıcı dizelerinden farklı ayırıcı dizeleri ayarlayarak yapabiliriz:

>>>print(json.dumps(data, separators=(',', ':')))
{"cats":[{"name":"Tubbs","color":"white"},{"name":"Pepper","color":"black"}]}

JSON çıktısını güzel yazdırmak için komut satırından json.tool’u çağırma

“foo.json” gibi bir JSON dosyası verildiğinde:

{"foo": {"bar": {"baz": 1}}}

modülü doğrudan komut satırından çağırarak (dosya adını argüman olarak geçerek) güzel bir şekilde yazdırabiliriz:

$ python -m json.tool foo.json
{
    "foo": {
        "bar": {
            "baz": 1
        }
    }
}

Modül ayrıca STDOUT’tan girdi alacaktır, bu nedenle (Bash’te) eşit şekilde yapabiliriz:

$ cat foo.json | python -m json.tool

JSON’dan Python dict oluşturma

import json
s = '{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}'
json.loads(s)

Yukarıdaki kod parçacığı aşağıdakileri döndürecektir:

{u'alice': 1, u'foo': u'bar', u'wonderland': [1, 2, 3]}

Python dict’ten JSON oluşturma

import json
d = {
    'foo': 'bar',
    'alice': 1,
    'wonderland': [1, 2, 3]
}
json.dumps(d)

Yukarıdaki kod parçacığı aşağıdakileri döndürecektir:

'{"wonderland": [1, 2, 3], "foo": "bar", "alice": 1}

JSON özel nesneleri kodlama

Eğer aşağıdakileri denersek:

import json
from datetime import datetime
data = {'datetime': datetime(2016, 9, 26, 4, 44, 0)}
print(json.dumps(data))

TypeError: datetime.datetime(2016, 9, 26, 4, 44) is not JSON serializable şeklinde bir hata alıyoruz.

Datetime nesnesini düzgün bir şekilde serileştirebilmek için, onu nasıl dönüştüreceğimize dair özel kod yazmamız gerekir:

class DatetimeJSONEncoder(json.JSONEncoder):
	def default(self, obj):
		try:
			return obj.isoformat()
		except AttributeError:
		# obj'nin isoformat yöntemi yoktur; bırakın bunu yerleşik JSON kodlayıcı halletsin
		return super(DatetimeJSONEncoder, self).default(obj)
		

ve sonra json.dumps yerine bu kodlayıcı sınıfını kullanın:

encoder = DatetimeJSONEncoder()
print(encoder.encode(data))
# prints {"datetime": "2016-09-26T04:44:00"}

load vs loads dump vs dumps

json modülü, hem unicode dizeleri okumak ve yazmak hem de dosyaları okumak ve yazmak için işlevler içerir. Bunlar, işlev adındaki sondaki s ile ayırt edilir. Bu örneklerde bir StringIO nesnesi kullandık, ancak aynı işlevler herhangi bir dosya benzeri nesne için de geçerli olacaktır.

Burada dize tabanlı fonksiyonları kullanırız:

import json

data = {u"foo": u"bar", u"baz": []}
json_string = json.dumps(data)
# u'{"foo": "bar", "baz": []}'
json.loads(json_string)
# {u"foo": u"bar", u"baz": []}

Ve burada dosya tabanlı fonksiyonları kullanıyoruz:

import json

from io import StringIO

json_file = StringIO()
data = {u"foo": u"bar", u"baz": []}
json.dump(data, json_file)
json_file.seek(0) # Okumadan önce dosyanın başlangıcına geri dönün
json_file_content = json_file.read()
# u'{"foo": "bar", "baz": []}'
json_file.seek(0) # Okumadan önce dosyanın başlangıcına geri dönün
json.load(json_file)
# {u"foo": u"bar", u"baz": []}

Gördüğünüz gibi temel fark, json verilerini dökerken dönüş değerini yakalamak yerine dosya tanıtıcısını işleve aktarmanız gerektiğidir. Ayrıca, veri bozulmasını önlemek için okumadan veya yazmadan önce dosyanın başlangıcını aramanız gerektiğini de belirtmek gerekir. Bir dosya açılırken imleç 0 konumuna yerleştirilir, bu nedenle aşağıdaki de çalışacaktır:

import json

json_file_path = './data.json'
data = {u"foo": u"bar", u"baz": []}

with open(json_file_path, 'w') as json_file:
    json.dump(data, json_file)

with open(json_file_path) as json_file:
    json_file_content = json_file.read()
    # u'{"foo": "bar", "baz": []}'

with open(json_file_path) as json_file:
    json.load(json_file)
    # {u"foo": u"bar", u"baz": []}

Json verileriyle başa çıkmanın her iki yoluna da sahip olmak, json üzerine inşa edilen formatlarla deyimsel ve verimli bir şekilde çalışmanıza olanak tanır – pyspark’ın json-per-line gibi:

# bir dosyadan yükleme
data = [json.loads(line) for line in open(file_path).splitlines()]

# bir dosyaya dökme
with open(file_path, 'w') as json_file:
    for item in data:
        json.dump(item, json_file)
        json_file.write('\n')

Bir yanıt yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Back to top