[Python3.6] F-String

Şu anda konuyu okuyanlar (Üyeler: 1, Ziyaretçi & Botlar: 0)


eymenbex

Üyecik
Katılım
8 Ağu 2018
Mesajlar
51
Puanları
8
Konum
Bursa
Merhabalar. Bugun sizlerle Python3.6 ile gelen f-string'leri inceleyeceğiz.




Normal stringler gibi davranan f-stringlerin genel amamcı string içinde python ifadeleri yazabilme olanağı sağlamasıdır.


f-stringler olmadan söyle yapıldığını hepimiz biliyoruz:

Kod:
isim = 'Omer'
string = "Merhabalar {}".format(isim)
print(string)

#Out:
#Merhabalar Omer


f-stringlerle bu islemi soyle yapabiliriz:


Kod:
isim = 'Omer'
string = f"Merhabalar {isim}"
print(string)

#Out
#Merhabalar Omer


f-stringlerin 'f' harfiyle baladığına dikkat edin.


Aslinda f-stringlerin en guzel yanı süslü parantezler içindeki deger ne olursa olsun, degerin string degerini otomatik olarak değistirmesi. f-string olmadan; ornek olarak 'int' tipinde bir degeri 'string' e cast etmemiz gerekirdi.

f-stringlerin icine koşul ifadeleri de koyabiliriz:

Kod:
isim = 'Ahmet'
string = f"Merhabalar {isim if isim == 'Ahmet' else 'Belirtilmedi'}"
print(string)

#Out:
#Merhabalar Ahmet

## Eger isim degeri 'Ahmet' olmasaydi ciktimiz soyle olurdu:
## Merhabalar Belirtilmedi



Simdi biraz değisik bir seyler yapalım:


Kod:
print(f"Sectiginiz sayilarin toplami: {int(input('Sayi1: ')) + int(input('Sayi2: '))}")


#Out:
#Sayi1: 12
#Sayi2: 2
#Sectiginiz sayilarin toplami: 14


Veya:


Kod:
isim = 'Ali'
yas = 6

print(f"{isim.upper()}'in yasi {yas} ve 10 yil sonra yasi {yas + 10} olacaktir...")


#Out
#ALI'nin yasi 6 ve 10 yil sonra yasi 16 olacaktir...



Alıntı:
ALcatraz'´isimli üyeden Alıntı

Aslında f-string'in kullanışından çok hızı çok önemli bence.
Mesela resmedilmiş bir örneği ;

Kod:
In [13]: timeit f'{a} + {b} = {a + b}'
12.4 ns ± 0.17 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)

In [14]: timeit '{} + {} = {}'.format(a, b, a + b)
510 ns ± 4.19 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [15]: timeit '%s + %s = %s' % (a, b, a + b)
366 ns ± 4.05 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Ve tabi böyle olmasının nedeni bytecodelardan kaynaklanıyor.
Dissambled bytecode'dan iki bytecode komutunu atlıyor: LOAD_ATTR ve CALL_FUNCTION. Sadece a ile b'yi toplayan bir fonksiyon çağıralım f-string ile beraber.


Kod:
dis.dis(add_two_fstring)
2 0 LOAD_CONST 1 (1)
2 STORE_FAST 0 (a)

3 4 LOAD_CONST 2 (2)
6 STORE_FAST 1 (b)

4 8 LOAD_FAST 0 (a)
10 LOAD_FAST 1 (b)
12 BINARY_ADD
14 FORMAT_VALUE 0
16 RETURN_VALUE
Str.format () kullandığımızda, format işlevinin öncelikle global değişken olarak"Araştırılması" gerekir. Bu LOAD_ATTR bytecode ile yapılır. Global değişken "Araştırılması" gerçekten kolay bir işlem değildir. .format()fonksiyonu bulunduğunda, a ve b değişkenlerini toplamak için ikili ekleme işlemi (BINARY_ADD) çağrılır. Son olarak, format fonksiyonu CALL_FUNCTION bytecode ile işleme devam eder ve belirtilen sonuçlar döndürülür. Hemen a ile b'yi toplayan fonksiyonun str.format() ile çağrılmasına göz atalım;


Kod:
dis.dis(add_two_string_format)

2 0 LOAD_CONST 1 (1)
2 STORE_FAST 0 (a)

3 4 LOAD_CONST 2 (2)
6 STORE_FAST 1 (b)

4 8 LOAD_CONST 3 ('{}')
10 LOAD_ATTR 0 (format)
12 LOAD_FAST 0 (a)
14 LOAD_FAST 1 (b)
16 BINARY_ADD
18 CALL_FUNCTION 1
20 RETURN_VALUE
Pythonda işlev çağırma gerçekten kolay bir işlem değildir ve büyük bir yüke sahiptir. str.format() işlevini kullanırken, LOAD_ATTR ve CALL_FUNCTION değerlerinde harcanan zaman, str.format() 'ın f-stringden çok daha yavaş olmasına katkıda bulunan şeydir.

Pardon pardon birde %-string vardı dimi?
Mesela %-string , str.format() 'a göre daha hızlı yukarıda da gördüğünüz gibi. Ama f-string'e göre daha yavaş peki %-string ' in str.format() 'a karşı hızlı olduğu yer neresi?Deminki gibi sadece a ile b'yi toplayan fonksiyon %-string ile çağrılmasına göz atalım ;


Kod:
dis.dis(add_two_percent_string_format)
2 0 LOAD_CONST 1 (1)
2 STORE_FAST 0 (a)

3 4 LOAD_CONST 2 (2)
6 STORE_FAST 1 (b)

4 8 LOAD_CONST 3 ('%s')
10 LOAD_FAST 0 (a)
12 BINARY_MODULO
14 LOAD_FAST 1 (b)
16 BINARY_ADD
18 RETURN_VALUE
Ee burada da LOAD_ATTR , CALL_FUNCTION yok? O zaman f-string ile aynı hızda olması gerekmez mi? Ama dikkatlice baktığımızda;


Kod:
dis.dis(add_two_percent_string_format)
2 0 LOAD_CONST 1 (1)
2 STORE_FAST 0 (a)

3 4 LOAD_CONST 2 (2)
6 STORE_FAST 1 (b)

4 8 LOAD_CONST 3 ('%s')
10 LOAD_FAST 0 (a)
12 BINARY_MODULO
14 LOAD_FAST 1 (b)
16 BINARY_ADD
18 RETURN_VALUE
BINARY_MODULO Cpython'un source'sinden bakabilirsiniz.

LINK - Bu kadar az olmasına rağmen yinede ciddi bir zaman kaybı var..

f-string kullanın iyidir.
Makaleyi yazan arkadaşında ellerine, emeğine sağlık.
Secrets modülünü de bekliyoruz



f-stringlerin oldukca kullanışlı olduğu ortada. Ama unutmayın f-stringler sadece Python 3.6'da çalışır.
 
Üst
stat counter