Python'da İfade ve İfade: Fark Nedir?


Python ile bir süre çalıştıktan sonra, sonunda benzer görünen iki terimle karşılaşacaksınız: ifade ve ifadesi . Resmi belgelere göz attığınızda veya çevrimiçi bir forumda python ile ilgili bir iş parçacığını kazdığınızda, insanların bu terimleri birbirinin yerine kullandıkları izlenimini edinebilirsiniz. Bu genellikle doğrudur, ancak kafa karıştırıcı bir şekilde, ifade vs ifade ayrımının önemli hale geldiği durumlar vardır.

Peki, Python'daki ifadeler ve ifadeler arasındaki fark nedir?

Kısacası: İfadelerin değerleri vardır ve ifadeleri yan etkilere neden olur

Python sözlüğünü açtığınızda aşağıdaki iki tanımı bulacaksınız:

İfade: Bir değere göre değerlendirilebilecek bir sözdizimi parçası. (…) (Kaynak)

İfadesi: Bir ifade, bir süitin (kodun bir bloğu ”) bir parçasıdır. Bir ifade ya bir ifadedir ya da anahtar kelimeli birkaç yapıdan biridir, (…) (kaynak)

Peki, bu pek de yararlı olmadı, değil mi? Neyse ki ifadeler ve ifadelerle ilgili en önemli gerçekleri üç nokta kadar kısa bir sürede özetleyebilirsiniz:

  1. Python'daki tüm talimatlar geniş ifadeler kategorisine girer.
  2. Bu tanıma göre, tüm ifadeler aynı zamanda ifadelerdir; bazen ifade ifadeleri de denir.
  3. Her ifade bir ifade değildir.

Teknik anlamda, her satır veya kod bloğu Python'da bir ifadedir. Bu, özel bir ifade türünü temsil eden ifadeleri içerir. Bir ifadeyi özel kılan nedir? Şimdi öğreneceksin.

İfadeler: Değer İçeren İfadeler

Esasen, kodunuzdaki tüm ifadeleri, programınızın genel davranışını değiştirmeden çalışma zamanında ürettikleri hesaplanan değerlerle değiştirebilirsiniz. Öte yandan ifadeler, ifadeler olmadıkça eşdeğer değerlerle değiştirilemez.

Aşağıdaki kod parçacığını göz önünde bulundurun:

>>> x = 42
>>> y = x + 8
>>> print(y)
50

Bu örnekte kodun her üç satırı da ifadeler içermektedir. İlk ikisi atama ifadeleridir, üçüncüsü ise print() işlevine yapılan bir çağrıdır.

Her satıra daha yakından baktığınızda, ilgili ifadeyi alt bileşenlere sökmeye başlayabilirsiniz. Örneğin, atama operatörü (=) soldaki ve sağdaki parçalardan oluşur. Eşit işaretin solundaki kısım, x veya y gibi değişken adını gösterir ve sağdaki parça bu değişkene atanan değerdir.

Value kelimesi buradaki anahtardır. x değişkenine, kodunuza pişirilmiş bir gerçek değer, 42 verildiğine dikkat edin. Buna karşılık, aşağıdaki satır y değişkenine x + 8 aritmetik bir ifade atar. Python, programınız çalışırken değişkenin nihai değerini belirlemek için önce böyle bir ifadeyi hesaplamalı veya değerlendirmelidir.

Aritmetik ifadeler Python ifadelerinin yalnızca bir örneğidir. Diğerleri mantıksal ifadeleri, koşullu ifadeleri ve daha fazlasını içerir. Hepsinin ortak noktası, değerlendirdikleri bir değer'dir; ancak her değer genellikle farklı olacaktır. Sonuç olarak, herhangi bir ifadeyi güvenli bir şekilde karşılık gelen değerle değiştirebilirsiniz:

>>> x = 42
>>> y = 50
>>> print(y)
50

Bu kısa program öncekiyle aynı sonucu verir ve işlevsel olarak öncekiyle aynıdır. Aritmetik ifadeyi elle hesapladınız ve ortaya çıkan değeri yerine eklediniz.

x + 8'i değerlendirebileceğinizi, ancak bir ifade içerse bile y=x + 8 atamasıyla aynı şeyi yapamayacağınızı unutmayın. Kod satırının tamamı, hiçbir içsel değeri olmayan saf bir ifadeyi temsil eder. Peki bu tür açıklamalar yapmanın ne anlamı var? Python ifadelerine dalıp öğrenmenin zamanı geldi.

Açıklamalar: Yan Etkileri Olan Talimatlar

İfade olmayan ifadeler, programınızın durumunu değiştiren veya diskteki bir dosya gibi harici bir kaynağı etkileyen yan etkilere neden olur. Örneğin bir değişkene değer atadığınızda, o değişkeni Python’un belleğinde bir yerde tanımlar veya yeniden tanımlarsınız. Benzer şekilde, print()'ı çağırdığınızda, varsayılan olarak metni ekranda görüntüleyen standart çıktı akışına (stdout) etkili bir şekilde yazarsınız.

Tamam aşkım. İfade olan ifadeleri ve ifade olmayan ifadeleri ele aldınız. Artık bunları sırasıyla salt ifadeler ve salt ifadeler olarak adlandırabilirsiniz. Ancak burada bir orta yol olduğu ortaya çıktı.

Bazı talimatların bir değeri olabilir ve aynı anda yan etkilere neden olabilir. Başka bir deyişle, yan etkileri olan veya eşdeğer bir değere sahip ifadelerdir. Bunun en iyi örneği Python’un Next() işlevi dilde yerleşik olacaktır:

>>> fruit = iter(["apple", "banana", "orange"])
>>> next(fruit)
'apple'
>>> next(fruit)
'banana'
>>> next(fruit)
'orange'

Burada, bir meyve isimleri listesi üzerinde yinelemenizi sağlayan meyve adlı bir yineleyici nesnesi tanımlarsınız. Bu nesnede next() 'i her çağırdığınızda, yineleyiciyi listedeki bir sonraki öğeye taşıyarak dahili durumunu değiştirirsiniz. Bu senin yan etkiniz. Eşzamanlı olarak, Next() Denklemin değer parçası olan karşılık gelen meyve adını döndürür.

Genel olarak, değerleri tek bir ifadede yan etkilerle karıştırmamak en iyi uygulama olarak kabul edilir. İşlevsel programlama saf işlevlerin kullanımını teşvik ederken, prosedür dilleri bir değer döndüren işlevler ile prosedürleri arasında bir ayrım yapar.

Son olarak, bu ilk başta mantığa aykırı gelse de Python'un hiçbir şeyi değerlendirmeyen veya herhangi bir yan etkiye neden olmayan bir ifadesi var. Ne olduğunu ve ne zaman kullanmak isteyeceğinizi tahmin edebilir misiniz? Size küçük bir ipucu vermek gerekirse, bilgisayar bilimlerinde genellikle no operasyon'un kısaltması olan no-op olarak bilinir.

Ne oldu? Bu Python pass ifadesidir! Bir ifadenin sözdizimsel olarak gerekli olduğu yerlerde genellikle onu yer tutucu olarak kullanırsınız, ancak herhangi bir işlem yapmak istemezsiniz. Bu yer tutucuları, gelişiminizin ilk aşamalarında boş işlev tanımlarında veya döngülerde kullanabilirsiniz. Python'un Elipsis (...)'i benzer bir amaca hizmet etse de, Elipsis'i bir ifade haline getiren bir değere sahip olduğunu unutmayın.

İfadelerin ve İfadelerin Özeti

Konuyu netleştirmek için aşağıdaki şemaya hızlıca bir göz atın. Python'daki farklı ifade ve ifade türlerini daha iyi anlamanıza yardımcı olacaktır:

Özetle, bir ifadesi , ister tek bir satır veya bir kod bloğu olsun, herhangi bir Python talimatı olabilir. Yukarıdaki diyagramdaki dört kadranın tamamı ifadeleri temsil eder. Bununla birlikte, bu terim genellikle sadece bir değeri olmadan yan etkilere neden olan saf ifadelere ifade etmek için kullanılır.

Buna karşılık, bir saf ifade , sadece yan etkilere neden olmadan bir değere değer değerlendiren özel bir ifade. Ayrıca, değere sahip ifadeler olan yan etkileri ile ifadelerle karşılaşabilirsiniz. Bunlar, yan etkilere neden olurken bir değer üreten ifadelerdir. Son olarak, bir no-op , ne bir değer üretmeyen ne de herhangi bir yan etkiye neden olmayan bir ifadedir.

Daha sonra onları vahşi doğada nasıl tanıyacağınızı öğreneceksiniz.

Python Talimatının İfade mi İfade mi Olduğunu Nasıl Kontrol Edebilirim?

Bu noktada her Python talimatının teknik olarak her zaman bir ifade olduğunu zaten biliyorsunuz. Dolayısıyla kendinize sormak isteyebileceğiniz daha spesifik bir soru, bir ifadeyle mi yoksa saf bir ifadeyle mi karşı karşıya olduğunuzdur. Bu soruyu iki yönlü yanıtlayacaksınız: Python'u kullanarak manuel olarak ve ardından programlı olarak.

Python REPL'de Manuel Olarak Kontrol Etme

Bu bölümde sorulan sorunun cevabını hızlı bir şekilde belirlemek için, siz yazarken ifadeleri değerlendiren Python REPL'in gücünden yararlanabilirsiniz. Bir talimat bir ifadeyse, çıktıda hemen değerinin varsayılan dize gösterimini görürsünüz:

>>> 42 + 8
50

Bu, 50 olarak değerlendirilen aritmetik bir ifadedir. Örneğin, ifadeyi bir değişkene atayarak veya onu bir işleve argüman olarak ileterek değerini yakalamadığınız için Python, hesaplanan sonucu sizin için görüntüler. Bir Python betiğinde aynı kod satırı mevcut olsaydı, yorumlayıcı değerlendirilen değeri göz ardı ederdi ve bu değer kaybolurdu.

Buna karşılık, REPL'de saf bir ifadenin çalıştırılması çıktıda hiçbir şey göstermez:

>>> import math
>>>

Bu, karşılık gelen bir değeri olmayan bir içe aktarma ifadesidir. Bunun yerine, belirtilen Python paketini bir yan etki olarak geçerli ad alanınıza yükler.

Ancak bu yaklaşımda dikkatli olmanız gerekir. Bazen hesaplanan bir değerin varsayılan dize temsili yanıltıcı olabilir. Bu örneği düşünün:

>>> fruit = {"name": "apple", "color": "red"}
>>> fruit.get("taste")
>>> fruit.get("color")
'red'

Bir meyveyi temsil eden bir Python sözlüğü tanımlarsınız. Üstünde ilk kez .get() adresini aradığınızda, görünür bir çıktı yoktur. Ama sonra, .get() 'i tekrar farklı bir anahtarla çağırırsınız ve o anahtarla ilişkili değeri döndürür, yani ' kırmızı '.

İlk durumda, .get(), sözlük "taste"None değerini döndürür. kodu >. Ancak, "color" gibi mevcut bir anahtarı kullandığınızda yöntem karşılık gelen değeri döndürür.

Python REPL, açıkça yazdırılmadığı sürece asla Yok öğesini görüntülemez; bu, bazen bu davranışın farkında değilseniz karışıklığa neden olabilir. Şüpheye düştüğünüzde, sonucun gerçek değerini ortaya çıkarmak için her zaman sonuçta print()'ı çağırabilirsiniz:

>>> fruit.get("taste")
>>> print(fruit.get("taste"))
None

Bu işe yararken, bir talimatın Python'da bir ifade olup olmadığını kontrol etmenin daha güvenilir bir yolu var.

Bir R değeri olup olmadığını kontrol etmek için bir değişkene talimat atayabilirsiniz. Aksi takdirde, saf bir ifade ise, bunu değişkeniniz için bir değer olarak kullanamazsınız ve bu hatayı alırsınız:

>>> x = import math
  File "<python-input-0>", line 1
    x = import math
        ^^^^^^
SyntaxError: invalid syntax

Python, bu ifadenin somut değeri olmadığı için bir değişkene içe aktarma ifadesi atayamayacağınızı söylemek için bir SynTaxError yükseltir.

Biraz özel bir durum olan zincir ataması, başlangıçta bunun bir ifade olup olmadığını kontrol etmek için x değişkenine y=42 atamaya çalışıyormuşsunuz gibi görünebilir:

>>> x = y = 42

Ancak bu, bu durumda x ve y ) birden fazla değişkeni yapar - aynı değere, 42 . İki ayrı atama yapmak için stenografi gösterimidir: x=42 ve y=42 .

Bir Python kodu parçasının bir ifade mi yoksa saf bir ifade mi olduğunu anlamanın başka bir yolu da onu parantez içine almaktır. Parantezler genellikle operatör önceliğine göre belirlenen varsayılan işlem sırasını değiştirmek için terimleri gruplamanıza yardımcı olur. Ancak ifadeleri değil yalnızca ifadeleri sarabilirsiniz:

>>> (2 + 2)
4

>>> (x = 42)
  File "<python-input-7>", line 1
    (x = 42)
     ^^^^^^
SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='?

Satır 1 dört olarak değerlendirilen bir ifade içerirken satır 4, Python'un bir atama ifadesini değerlendirmeyi başarısız bir şekilde denemesi nedeniyle sözdizimi hatasına yol açar. Görüntülenen hata mesajı, atama operatörünü (=) değer eşitliği (==) veya mors operatörü (:= ) olarak değiştirmenizi ister ).

Şu ana kadar Python REPL'de ifadeleri ve ifadeleri manuel olarak karşılaştırdınız. Bir sonraki bölümde, bunu programlı olarak nasıl yapacağınızı öğreneceksiniz; bu, otomatikleştirmek istediğiniz tekrarlanan bir görevse size yardımcı olabilir.

Bir Python İfadesi Oluşturma Vs Detekleme Dedektörü

Bir talimatın programlı olarak bir ifade mi yoksa ifade mi olduğunu belirlemek için Python'un eval() ve exec() yerleşik işlevlerini çağırabilirsiniz. İlk işlev, ifadeleri dinamik olarak değerlendirmenize olanak tanır ve ikincisi, bir dizeden isteğe bağlı kod çalıştırabilir:

>>> eval("2 + 2")
4
>>> exec("x = 42")
>>> print(x)
42

"2 + 2" dizesi, eval()'ın 4 tamsayısını değerlendirdiği bir Python ifadesi içerir. İsterseniz eval() tarafından döndürülen değeri bir değişkene atayabilirsiniz. Öte yandan, exec() hiçbir şey döndürmez ancak yan etkilere neden olur. Aynı kapsam içinde bu işlevi çağırdıktan sonra exec() işlevine iletilen dizede tanımlanan değişkene nasıl erişebileceğinize dikkat edin.

Her iki işlev de, giriş dizesi geçerli bir ifade veya ifade olmadığında bir sözdizimi hatası bildirir:

>>> eval("2 +")
Traceback (most recent call last):
  ...
SyntaxError: invalid syntax

>>> exec("x = 2 +")
Traceback (most recent call last):
  ...
SyntaxError: invalid syntax

Ayrıca, eval(), sağlanan dize değer içermeyen saf bir ifade içerdiğinde sözdizimi hatasına neden olur. Aynı zamanda, aynı ifade exec() ile gayet iyi çalışıyor:

>>> eval("x = 2 + 2")
Traceback (most recent call last):
  ...
SyntaxError: invalid syntax

>>> exec("x = 2 + 2")

İfadeler ve saf ifadeler arasında ayrım yapmak için bu tutarsızlıktan yararlanabilirsiniz. Ancak yanlış pozitiflerden kaçınmak için exec() 'den önce değerlendirme() çağırmayı unutmayın. Tüm ifadeler ifadeler olduğundan, exec() , bir argüman olarak bir ifade veya ifade alıp almadığını neredeyse her zaman başarılı olacaktır:

>>> eval("print('Hello, World!')")
Hello, World!

>>> exec("print('Hello, World!')")
Hello, World!

Her iki işlev de size aynı sonuç verir: Merhaba Dünya! . exec() aradıysanız ve orada durduysanız, yanlışlıkla kodun geçerli bir ifade olabileceği bir ifade olduğu sonucuna varabilirsiniz. Bu arada, Python'daki tüm işlev çağrıları teknik olarak ifadelerdir ve bu şekilde sınıflandırılmalıdır. Bunu nasıl ele alabilirsiniz.

Kod çoğaltmasını önlemek için, değerlendirme() hem de exec() 'ı, ast.parse() adresine delege eden tek bir işlevde birleştirebilirsiniz. Uygun modla:

>>> import ast

>>> def valid(code, mode):
...     try:
...         ast.parse(code, mode=mode)
...         return True
...     except SyntaxError:
...         return False
...

>>> valid("x = 2 + 2", mode="eval")
False

>>> valid("x = 2 + 2", mode="exec")
True

Bu işlev bir Python code pasajını ve iki değerden birini alabilen mode parametresini kabul eder: "eval" veya "exec ". Temel ifade veya ifade sözdizimsel olarak yanlış olduğunda işlev False değerini döndürür. Aksi takdirde, kod belirtilen modda başarıyla çalıştırıldığında True değerini döndürür.

Üstüne üstlük, verilen kod pasajının metinsel gösterimini sağlayacak başka bir yardımcı fonksiyon yazabilirsiniz:

>>> def describe(code):
...     if valid(code, mode="eval"):
...         return "expression"
...     elif valid(code, mode="exec"):
...         return "statement"
...     else:
...         return "invalid"
...

>>> describe("x = 2 + 2")
'statement'

>>> describe("2 + 2")
'expression'

>>> describe("2 +")
'invalid'

Öncelikle verilen kodun bir ifade olup olmadığını kontrol edersiniz. Öyle olduğunda, "ifade" dizesini döndürürsünüz. Değilse, kodun bir ifade olup olmadığını kontrol edebilirsiniz. Bir ifade olarak nitelendiriliyorsa "statement" dizesini döndürürsünüz. Son olarak, her iki koşul da karşılanmazsa kodun "geçersiz" olduğu sonucuna varırsınız.

Bu yaklaşım, herhangi bir nedenle böyle bir testi programlı olarak gerçekleştirmeniz gerektiğinde yardımcı olabilir. Belki Python'da yapısal desen eşleştirmeyi kullanarak kendi Python REPL'inizi oluşturuyorsunuz ve değerlendirilen bir ifadeyi ne zaman görüntüleyeceğinize karar vermeniz gerekiyor.

Şimdiye kadar Python'daki ifadeler ve ifadeler arasındaki farkı daha sezgisel olarak anlamalısınız. Hangisinin hangisi olduğunu da söyleyebilmelisiniz. Bir sonraki önemli soru, bunun yalnızca sadelik meraklıları için anlamsal bir ayrım olup olmadığı veya günlük kodlama pratiğinizde herhangi bir önemi olup olmadığıdır. Şimdi öğreneceksin!

Bu Fark Günlük Programlamanızda Önemli mi?

Çoğu zaman, Python'da bir ifade veya bir ifade ile çalışıp çalışmadığınız hakkında çok fazla düşünmenize gerek yoktur. Bununla birlikte, bahsetmeye değer iki önemli istisna vardır:

  1. lambda ifadeleri
  2. assert ifadeleri

Birincisi ile başlayacaksınız, yani lambda ifadesi.

Lambda İfadesi

Python'un lambda anahtar sözcüğü, anonim bir işlev tanımlamanıza olanak tanır; bu, sıralama anahtarını veya filtrelenecek koşulu belirtmek gibi tek seferlik işlemler için yararlı olabilir:

>>> fruits = [("apple", 2), ("banana", 0), ("orange", 3)]

>>> sorted(fruits, key=lambda item: item[1])
[('banana', 0), ('apple', 2), ('orange', 3)]

>>> list(filter(lambda item: item[1] > 0, fruits))
[('apple', 2), ('orange', 3)]

Burada, bir meyvenin adını ve ilgili miktarını içeren iki elemanlı tüfeklerin bir listesini tanımlarsınız. Ardından, bu listeyi miktara göre artan sırada sıralayacaksınız. Son olarak, listeyi filtreleyerek yalnızca en az bir birimi olan meyveleri bırakırsınız.

Bu, derhal kullanımlarının ötesinde bu tür satır içi işlevlere başvurmanız gerekmediği sürece uygun bir yaklaşımdır. Daha sonra kullanım için bir değişkene her zaman bir lambda ifadesi atayabilirsiniz, ancak def ile tanımlanan normal bir işlevle sözdizimsel olarak eşdeğer değildir.

İşlev tanımı, işlevin gövdesini temsil eden yeni bir kod bloğu başlatır. Python'da hemen hemen her kod bloğu bileşik bir ifadeye aittir, dolayısıyla değerlendirilemez.

İfadelerin değerleri olmadığından, bir Lambda ifadesi ile yapabileceğiniz gibi bir değişkene işlev tanımı atayamazsınız:

>>> inline = lambda: 42

>>> regular = (
...     def function():
...         return 42
... )
...
  File "<python-input-1>", line 2
    def function():
    ^^^
SyntaxError: invalid syntax

inline değişkeni, lambda olarak tanımlanan anonim bir işleve referans tutarken, regular, adlandırılmış bir işlev tanımını bir işleve atamaya yönelik başarısız bir girişimdir. değişken.

Ancak, başka bir yerde zaten tanımlanmış bir bir işleve referans atamanıza izin verilir:

>>> def function():
...     return 42
...
>>> alias = function

def function(): ifadesinin ve onun altında görünen function referansının farklı anlamlarına dikkat edin. Birincisi, fonksiyonun ne yaptığının taslağı, ikincisi ise fonksiyonu çağırmadan dolaşabileceğiniz fonksiyonun adresidir.

lambda anahtar kelime ile tanımlanan bir işlev, vücudunda her zaman tam olarak bir ifade içermelidir. return ifadesini eklemeniz gerekmeden değerlendirilecek ve dolaylı olarak iade edilecektir. Aslında, lambda işlevlerinde ifadelerin kullanılması açıkça yasaktır. Bunları kullanmaya çalışırsanız, sözdizimi hatasına neden olursunuz:

>>> lambda: pass
  File "<python-input-0>", line 1
    lambda: pass
            ^^^^
SyntaxError: invalid syntax

pass'ın bir ifade olduğunu, dolayısıyla lambda ifadesinde yeri olmadığını öğrendiniz. Ancak bunun için bir çözüm var. Her zaman bir veya daha fazla ifadeyi bir işleve sarabilir ve bu işlevi lambda ifadenizde şu şekilde çağırabilirsiniz:

>>> import tkinter as tk

>>> def on_click(age):
...     if age > 18:
...         print("You're an adult.")
...     else:
...         print("You're a minor.")
...

>>> window = tk.Tk()
>>> button = tk.Button(window, text="Click", command=lambda: on_click(42))
>>> button.pack(padx=10, pady=10)
>>> window.mainloop()

Bu, Tkinter ile oluşturulmuş bir grafik kullanıcı arayüzü (GUI) içeren minimal bir Python uygulamasıdır. Vurgulanan satır, düğmenin tıklama olayı için bir dinleyiciyi kaydeder. Olay işleyicisi, koşullu bir ifadeyi kapsülleyen bir sarmalayıcı işlevi çağıran satır içi bir lambda ifadesi olarak tanımlanır. Bu kadar karmaşık bir mantığı yalnızca lambda ifadesiyle ifade edemezsiniz.

İddia Beyanı

assert ifadesine gelince, onu çevreleyen ortak bir kafa karışıklığı var ve bu da biraz yanıltıcı sözdiziminden kaynaklanıyor. assert'in bir ifade olduğunu ve sıradan bir işlev çağrısı gibi davranmadığını unutmak çok kolaydır. Bu bazen dikkatli olmadığınızda istenmeyen davranışlara neden olabilir.

En temel biçiminde, assert anahtar sözcüğünün ardından bir mantıksal yüklem veya Boole değeri olarak değerlendirilen bir ifade gelmelidir:

>>> assert 18 < int(input("What's your age? "))
What's your age? 42

>>> assert 18 < int(input("What's your age? "))
What's your age? 15
Traceback (most recent call last):
  ...
AssertionError

İfade doğru olursa hiçbir şey olmaz. İfade yanlışsa, iddiaları bir komut satırı seçeneği veya ortam değişkeniyle tamamen devre dışı bırakmamış olmanız koşuluyla Python bir AssertionError oluşturur.

İsteğe bağlı olarak, yükseltilmiş iddia hatasıyla birlikte görüntülenecek özel bir hata mesajını ekleyebilirsiniz. Bunu yapmak için, yüklemden sonra bir virgül yerleştirin ve bir ipin gerçek - veya bir tane olarak değerlendirilen herhangi bir ifade ekleyin:

>>> assert 18 < int(input("What's your age? ")), "You're a minor"
What's your age? 15
Traceback (most recent call last):
  ...
AssertionError: You're a minor

Şimdiye kadar, çok iyi. Ancak daha uzun bir hata mesajı eklemek kodun daha az okunabilir olmasına neden olabilir ve bu da sizi bir şekilde bu satırı kırmaya teşvik edebilir.

Python, açık bir ters eğik çizgi (\) kullanmadan uzun bir talimatı birden çok satıra bölmenize olanak tanıyan örtülü satır devamı adı verilen güzel bir özellik sunar. Bunu, ifadelerinizi parantez, köşeli parantez veya küme parantezi içine alarak kodu daha düzenli ve okunması kolay hale getirerek başarabilirsiniz:

>>> assert (
...     18 < int(input("What's your age? ")),
...     "You're a minor"
... )
<python-input-0>:1: SyntaxWarning: assertion is always true, perhaps remove parentheses?
  assert (
What's your age? 15
>>>

Bu genellikle işe yarar, ancak bu durumda değil. Gördüğünüz gibi modern Python sürümleri, bir şeylerin muhtemelen yanlış olduğunu size bildirmek için bir uyarı bile yayınlayacaktır.

Anahtar kelimeden hemen sonra bir assert ifadesinin bir ifade beklediğini unutmayın. Yüksek lisans ve özel mesajınızı parantez ile çevrelediğinizde, esasen tek bir ifade olarak ele alınan bir tuple tanımlarsınız. Python bu tür boş olmayan dizileri true olarak değerlendirir. Dolayısıyla, assert ifadeniz, kontrol etmeye çalıştığınız gerçek durumdan bağımsız olarak her zaman geçer.

Bu sorunu önlemek için, uzun bir satırı kesmek istediğinizde açık bir satır devamı kullanmak daha iyidir:

>>> assert 18 < int(input("What's your age? ")), \
...     "You're a minor"
What's your age? 15
Traceback (most recent call last):
  ...
AssertionError: You're a minor

Artık yüklem doğru değerlendirildiği için beklenen davranışı tekrar gözlemliyorsunuz.

Daha önce, Python'daki kod bloklarının bileşik ifadelerin bir parçası olduğunu öğrendiniz. Daha sonra, Python'daki basit ve bileşik ifadeler arasındaki farkları keşfedeceksiniz.

Python'da Basit ve Bileşik İfadeler Nelerdir?

İfadeler, Python programlarınızın temel yapı taşlarıdır. Yürütme akışını kontrol etmenize ve değişkenlere değer atama gibi eylemleri gerçekleştirmenize izin verirler. İfadeleri iki birincil türe kategorize edebilirsiniz:

  1. Basit ifadeler
  2. Bileşik İfadeler

Basit ifadeler tek bir satıra sığabilirken, bileşik ifadeler tipik olarak bir birden fazla girintili kod satırını ve ardından yeni bir çizgi karakterini kapsayan diğer ifadeler içerir.

Aşağıdaki tablo, her iki ifade türünün bazı yaygın örneklerini göstermektedir:

assert age > 18

yaş> 18: ...

import math

while True: ...

return 42

_ aralıkta (3): ...

pass

dene: ...

x = 42 + 8

def ekle(x, y): ...

Gördüğünüz gibi, basit ifadeler belirli bir yan etkiye neden olur - geçiş ifadesi hariç. Bileşik ifadeler ise döngüler, koşullar ve işlev tanımları gibi geleneksel kontrol akışı yapılarını içerir.

Bileşik ifadelere daha yakından baktığınızda, bunların her biri bir başlık ve bir süet içeren bir veya daha fazla cümleden oluştuğunu göreceksiniz. Örnek olarak aşağıdaki koşullu ifadeyi düşünün:

if age > 18:
    print("Welcome!")
elif age < 18:
    raise ValueError("You're too young to be here.")
else:
    import sys
    sys.exit(1)

Vurgulanan çizgiler, bileşik ifadesinin cümle başlıklarını tasvir ederken, kalan çizgiler karşılık gelen süitlerini temsil eder. Örneğin, ise yaşın on sekizden büyük olup olmadığını kontrol eder ve koşullu olarak print() işlevini paketinde çağırır.

Bileşik ifadedeki tüm cümle başlıkları aynı girinti düzeyinde hizalanır. if, elif veya else gibi bir Python anahtar sözcüğüyle başlarlar ve iki nokta üst üste (: ) ile biterler ) paketin kod bloğunun başlangıcını işaret eder. Bir paket, ilgili maddesine tabi olan ifadelerin bir koleksiyonudur. Bu durumda üç madde, yaş durumuna göre hangi süitlerin çalıştırılacağını belirler.

İfade listesi olarak bilinen ve bir dizi basit ifadeden oluşan özel bir bileşik ifade türü vardır. Her birinin tek bir satıra yerleştirilmesi gerekmesine rağmen, birden fazla basit ifadeyi tek bir satıra sıkıştırabilirsiniz. Nasıl olduğunu biliyor musun?

Tek Satıra Birden Fazla İfade Nasıl Yerleştirilir?

Çoğu durumda, okunabilirlik açısından her satıra yalnızca bir ifade veya ifade yerleştirmek tercih edilir. Ancak aynı satıra birden fazla sayıda sığdırmakta ısrar ediyorsanız, ifade ayırıcı olarak noktalı virgül (;) kullanabilirsiniz.

Bunun yararlı olabileceği popüler bir kullanım örneği, python -c seçeneğini kullanarak komut satırında tek satırlık bir program çalıştırmayı içerir:

$ python -c 'import sys; print(sys.version)'
3.13.0 (main, Oct 19 2024, 15:05:58) [GCC 13.2.0]

Bu, fikirleri kısa kod parçacıkları şeklinde hızlı bir şekilde test etmenizi sağlar. Ancak bu günlerde, çoğu terminal, herhangi bir sorun olmadan kodu birden fazla satıra yaymanıza izin verir:

$ python -c '
> import sys
> print(sys.version)
> '
3.13.0 (main, Oct 19 2024, 15:05:58) [GCC 13.2.0]

Python yorumlayıcısının beklediği komut birden fazla satırdan oluşabilir.

Noktalı virgül için bir başka yaygın kullanım durumu, kodunuza bir kesme noktası eklemektir. Yerleşik BreakPoint() işlevini tanıtan Python 3.7'den önce, aşağıdaki deyimsel kod satırı ile hata ayıklayıcıya atlarsınız:

import pdb; pdb.set_trace()

Tercüman pdb.set_trace() isabet ettiğinde, yürütmeyi duraklatır ve Python hata ayıklayıcısını (PDB) kullanarak etkileşimli hata ayıklama oturumuna girersiniz.

Ayrıca, Python kodunuzu kasıtlı olarak gizlemek veya bir dereceye kadar minnettar olmak için bu hileyi kullanmayı deneyebilirsiniz. Bununla birlikte, bazı sözdizimsel sınırlamalardan kaçamazsınız, bu nedenle Pirarmor gibi harici araçlarla daha iyi sonuçlar elde edersiniz.

Bu öğreticiyi kapatmadan önce Python'daki ifadeler ve deyimlerle ilgili son bir soruyu yanıtlamanız gerekiyor. Size daha gelişmiş programlama zorluklarının üstesinden gelmeniz için temel sağlayacak bir şey.

İfadeler Python'da çift doğaya sahip olabilir mi?

Python'daki tüm talimatlar ifadeler olduğundan, yan etkileri olan bir ifadeyi hesaplanan değeri dikkate almadan çalıştırabilirsiniz. Bu genellikle bir işlevi veya yöntemi çağırdığınızda ancak dönüş değerini göz ardı ettiğinizde meydana gelir:

>>> with open("file.txt", mode="w", encoding="utf-8") as file:
...     file.write("Hello, World!")
...
13

Yukarıdaki örnekte, bir dosya nesnesinin .write() yöntemini bağımsız değişken olarak "Merhaba, Dünya!" dizesiyle çağırırsınız. Bu yöntem, yazılan karakter sayısını (on üç) döndürse de, döndürülen değeri bir değişkene müdahale etmeyerek veya herhangi bir şekilde daha fazla işlemeyerek bunları göz ardı edersiniz. Ancak bu durumda Python REPL'in en son değerlendirilen ifadenin sonucunu otomatik olarak görüntülediğine dikkat edin.

Tamam aşkım. Yani eğer varsa sadece yan etkileri için ifadelerden yararlanabilirsiniz. Peki ya tam tersi? İfadeleri değerlendirebilir misiniz? Öğrenmek üzeresiniz!

Atamalar

Bazı programlama dilleri ifadeler ve ifadeler arasındaki çizgileri bulanıklaştırır. Örneğin, bir atama ifadesini C veya C ++ 'da değerlendirebilirsiniz:

#include <stdio.h>

int main() {
    int x;
    while (x = fgetc(stdin)) {
        if (x == EOF)
            break;
        putchar(x);
    }
    return 0;
}

Bu kısa program, klavyede kullanıcının yazdığı her şeyi yansıtır. Standart girişten bir sonraki karakteri alan ve yerel bir değişken olan x adresine atanan vurgulanan satıra dikkat edin. Eşzamanlı olarak, bu atama bir boole ifadesi olarak değerlendirilir ve döngüsü olmak üzere için bir devam koşulu olarak kullanılır. Başka bir deyişle, giriş karakterinin sıralı sayısı sıfır dışında olduğu sürece, döngü devam eder.

Bu, çağlar boyunca C ve C++ programlarını rahatsız eden kötü şöhretli bir hata kaynağı olmuştur. Programcılar, görsel benzerlikleri nedeniyle sıklıkla yanlışlıkla amaçlanan eşitlik testi operatörü (==) yerine atama operatörünü (=) kullanırlar. Yukarıdaki örnekte bu özellik kasıtlı olarak kullanılmış olsa da, bu genellikle beklenmeyen davranışlara yol açabilecek insan hatasının bir sonucuydu.

Uzun bir süre, çekirdek geliştiriciler bu potansiyel karışıklıkla ilgili endişeler nedeniyle Python'da benzer bir özellik uygulamaktan kaçındı. atama ifadeleri 'a izin vermek için mors operatörünü (:=) tanıtan Python 3.8'e kadar durum buydu:

MAX_BYTES = 1024

buffer = bytearray()
with open("audio.wav", mode="rb") as file:
    while chunk := file.read(MAX_BYTES):
        buffer.extend(chunk)

Bu kod snippet'inde, boş bir parça ile gösterilen dosya sonu kontrol baytında tökezleyene kadar ikili parçalarda bir WAV dosyasını aşamalı olarak okursunuz. Bununla birlikte, .read() tarafından döndürülen yastığın boş olup olmadığını veya true olarak değerlendirilip değerlendirilmediğini açıkça kontrol etmek yerine-uygulamak ve değerlendirmek için atama ifadesinden yararlanıyorsunuz. Bir adımda görev.

Bu, aksi takdirde şu şekilde görünecek olan birkaç satır koddan tasarruf etmenizi sağlar:

MAX_BYTES = 1024

buffer = bytearray()
with open("audio.wav", mode="rb") as file:
    while True:
        chunk = file.read(MAX_BYTES)
        if not chunk:
            break
        buffer.extend(chunk)

Deterministik bir döngüyü sonsuz bir döngüye dönüştürdünüz ve üç ifade daha eklediniz: atama ifadesi, koşullu ifade ve break ifadesi.

C örneğinden farklı olarak, atama ifadesini ifade karşılığı ile karıştırmanın bir yolu yoktur. Python, boole bağlamında atama beyanlarına izin vermemeye devam ediyor. Bu gibi durumlarda, Python Zen'den aforizmalardan biriyle güzel hizalanan mors operatörünü açıkça kullanmalısınız:

Açık, örtük olmaktan daha iyidir. (Kaynak)

Python'da ifade benzerlerine sahip başka ifade örnekleri de vardır. Daha sonra koşullu ifadelere ve ifadelere bakacaksınız.

Koşullu ifadeler

Birçok programlama dili, üç öğeyi birleştiren bir üçlü koşullu operatör sağlar: mantıksal bir koşul, durum true olarak değerlendirirse bir değer ve durumun değerlendirilmesi durumunda alternatif bir değer false .

C-ailesi dillerinde, üçlü operatör ( ?: ) Elvis Presley’nin ifadesini kendine özgü saç stiliyle andırıyor. Bu diller buna Elvis operatörü olarak adlandırılırken, Python daha muhafazakar şartlı ifadeye bağlı kalır. İşte böyle görünüyor:

>>> def describe(users):
...     if not users:
...         print("No people")
...     else:
...         print(len(users), "people" if len(users) > 1 else "person")
...

>>> describe([])
No people

>>> describe(["Alice"])
1 person

>>> describe(["Alice", "Bob"])
2 people

İlk bakışta, Python’un koşullu ifadesi, tek bir çizgiye yoğunlaşan standart koşullu ifadeye benzemektedir. Gerçek bir değerle ilişkili bir ifade ile başlar, ardından kontrol etme koşulu ve daha sonra bir falsy değerine karşılık gelen ifade ile başlar. Normalde koşullu bir ifadenin kullanılmasını gerektiren koşullu mantığı değerlendirmenizi sağlar.

Anlamalar

Gri alanı kaplayan ifadelere başka bir örnek, açık döngülerden kaçınmak için yararlanabileceğiniz, liste anlama veya oluşturucu ifade gibi her türlü anlama ifadesi'dir:

>>> fruits = [("apple", 2), ("banana", 0), ("orange", 3)]
>>> sorted(name.title() for name, quantity in fruits if quantity > 0)
['Apple', 'Orange']

Sözdizimi yine for döngüsüne ve if ifadesine benzer, ancak bunları tek bir satıra daraltır ve ayrı ayrı parçalarını yeniden düzenlersiniz. Bu yalnızca, değerlendirilecek koşul ve ifade, onları bir veya iki satıra sığdırabilecek kadar küçük olduğunda işe yarar. Aksi takdirde, okunması zor, karmaşık bir kod parçasıyla karşı karşıya kalırsınız.

Son olarak, Python jeneratörleri burada bahsetmeyi hak ediyorlar çünkü aynı anda hem ifade hem de bir ifade olabilecek sözdizimi kullanıyorlar.

Jeneratörler

yield ve yield from anahtar sözcükleri, büyük veri akışlarını verimli bir şekilde yönetmenize veya eşyordamları tanımlamanıza olanak tanıyan oluşturucu işlevlerin içinde görünür.

Bir jeneratör işlevinden değerler üretmek istediğinizde Python'un verim 'i bir ifade olarak yürütmesine izin verdiniz:

>>> import random

>>> def generate_noise(size):
...     for _ in range(size):
...         yield 2 * random.random() - 1
...

>>> list(generate_noise(3))
[0.7580438973021972, 0.5273057193944659, -0.3041263216813208]

Bu oluşturucu, -1 ile 1 arasındaki rastgele değerlerin üreticisidir. Burada yield'in kullanılması, return ifadesinin kullanılmasına biraz benzer. Bir yan etki olarak çağırana bir dizi değer iletir, ancak yield ifadesi, işlevi tamamen sonlandırmak yerine, işlevin yürütülmesini askıya alarak daha sonra devam etmesine ve devam etmesine olanak tanır.

Şimdi, jeneratörünüzü potansiyel olarak birçok giriş ve çıkış noktasıyla bir prosumciye (üretici ve tüketici) dönüştürmek için isteğe bağlı olarak verim 'ı bir ifade olarak değerlendirebilirsiniz. Her verim ifade her iki yönde de değer sağlayabilir ve alabilir. Verilen değerler jeneratörün çıkışını temsil ederken, jeneratöre geri gönderilen değerler giriştir:

>>> def lowpass_filter():
...     a = yield
...     b = yield a
...     while True:
...         a, b = b, (yield (a + b) / 2)
...

İlk verim ifadesi dolaylı olarak hiçbir şey vermez ( none ), ancak bir ifade olarak değerlendirildiğinde dış dünyadan bir değer alır. Bu değer daha sonra a adlı yerel bir değişkene atanır.

İkinci yield ifadesi a'yı verirken aynı anda b'de başka bir değer depolar. Bu noktada filtre doymuş hale gelir ve gelen verileri işlemeye hazır hale gelir. Her askı noktasında değer tüketme ve üretme yeteneği (verim), bir elektrik akımının bir devreden akması gibi, bir sinyali filtrenizden geçirmeyi mümkün kılar.

Son yield ifadesi her iki sayının ortalamasını hesaplar ve verir, a'nın üzerine b ile yazar ve ardından b'ye yeni bir değer atar. .

Sinyali yumuşatan iki noktalı hareketli ortalamayı hesaplayan alçak geçiş filtrenizdeki .send()'i çağırarak her iki jeneratörü de birbirine bağlayabilirsiniz:

>>> lf = lowpass_filter()
>>> lf.send(None)
>>> for value in generate_noise(10):
...     print(f"{value:>5.2f}: {lf.send(value):>5.2f}")
...
 0.66:  0.66
-0.01:  0.32
 0.30:  0.15
-0.10:  0.10
-0.98: -0.54
 0.79: -0.10
 0.31:  0.55
-0.10:  0.11
-0.25: -0.18
 0.57:  0.16

Sol sütundaki sayılar doğrudan gürültü üretecinden gelir ve doğrudan alçak geçiş filtresine beslenir. Sağ sütun bu filtrenin çıktısını içerir. İlk yield ifadesine ilerlemesi için öncelikle üreten tüketicinizi None göndererek veya next()'i çağırarak hazırlamanız gerektiğini unutmayın.

Çözüm

Bu öğreticide, Python'da ifadeleri ve ifadeleri arasındaki temel farklılıkları araştırdınız. İfadelerin bir değerini olarak değerlendiren sözdizimi parçaları olduğunu öğrendiniz, ifadeler ise yan etkilere neden olabilecek talimatlardır. Aynı zamanda aralarında gri bir alan var.

Bu ayrımı anlamak Python geliştiricileri için çok önemlidir çünkü kodunuzu yazma ve yapılandırma şeklinizi etkiler. Artık bu becerilere sahip olduğunuza göre, daha kesin ve anlamlı Python kodu yazabilir, sağlam ve verimli programlar oluşturmak için ifadelerden ve ifadelerden tam olarak yararlanabilirsiniz.