Zephyrnet Logosu

Python'da Sık Karşılaşılan 5 Sorun (Ve Bunlardan Nasıl Kaçınılacağı) – KDnuggets

Tarih:

Python'da Sık Karşılaşılan 5 Sorun (Ve Bunlardan Nasıl Kaçınılır)
Yazara göre resim
 

Python, basitliği ve okunabilirliği ile bilinen, başlangıç ​​seviyesi dostu ve çok yönlü bir programlama dilidir. Ancak zarif sözdizimi, deneyimli Python geliştiricilerini bile şaşırtabilecek tuhaflıklara karşı bağışık değildir. Ve bunları anlamak, hatasız kod yazmak veya isterseniz sorunsuz hata ayıklamak için çok önemlidir.

Bu eğitimde bu sorunlardan bazıları inceleniyor: değişken varsayılanlar, döngülerde ve kavramalarda değişken kapsam, demet ataması ve daha fazlası. Görmek için basit örnekleri kodlayacağız neden işler öyle yürüyor ve aynı zamanda şuna da bakın: Nasıl bunlardan kaçınabiliriz (eğer gerçekten yapabilirsek 🙂). 

Hadi başlayalım!

Python'da değiştirilebilir varsayılanlar yaygın olarak kullanılan keskin köşelerdir. Varsayılan argümanlar olarak listeler veya sözlükler gibi değiştirilebilir nesneler içeren bir işlevi tanımladığınızda beklenmedik davranışlarla karşılaşırsınız. 

Varsayılan değer, işlev tanımlandığında yalnızca bir kez değerlendirilir ve işlev her çağrıldığında değerlendirilmez.. Bu, işlev içindeki varsayılan bağımsız değişkeni değiştirirseniz beklenmeyen davranışlara yol açabilir.

Bir örnek verelim:

def add_to_cart(item, cart=[]):
    cart.append(item)
    return cart

 

Bu örnekte, add_to_cart bir öğeyi alıp onu bir listeye ekleyen bir işlevdir cart. varsayılan değeri cart boş bir listedir. Eklenecek bir öğe olmadan işlevin çağrılması, boş bir sepet döndürme anlamına gelir. 

Ve işte birkaç işlev çağrısı:

# User 1 adds items to their cart
user1_cart = add_to_cart("Apple")
print("User 1 Cart:", user1_cart)  

 

Output >>> ['Apple']

 

Bu beklendiği gibi çalışıyor. Peki şimdi ne olacak?

# User 2 adds items to their cart
user2_cart = add_to_cart("Cookies")
print("User 2 Cart:", user2_cart) 

 

Output >>>

['Apple', 'Cookies'] # User 2 never added apples to their cart!

 

Varsayılan argüman bir liste (değiştirilebilir bir nesne) olduğundan, işlev çağrıları arasında durumunu korur. Yani her aradığında add_to_cartdeğeri, işlev tanımı sırasında oluşturulan aynı liste nesnesine ekler. Bu örnekte tüm kullanıcılar aynı sepeti paylaşıyor gibi.

Nasıl Kaçınılır?

Geçici bir çözüm olarak şunları ayarlayabilirsiniz: cart için None ve fonksiyonun içindeki sepeti şu şekilde başlatın:

def add_to_cart(item, cart=None):
    if cart is None:
        cart = []
    cart.append(item)
    return cart

 

Yani artık her kullanıcının ayrı bir sepeti var. 🙂

Python işlevleri ve işlev argümanları hakkında bilgilerinizi tazelemeye ihtiyacınız varsa şunu okuyun: Python İşlev Argümanları: Kesin Bir Kılavuz.

Python'un kapsam tuhaflıkları, kendilerine ait bir eğitim gerektirir. Ancak burada böyle bir tuhaflığa bakacağız.

Aşağıdaki parçaya bakın:

x = 10
squares = []
for x in range(5):
    squares.append(x ** 2)

print("Squares list:", squares)  

# x is accessible here and is the last value of the looping var
print("x after for loop:", x)

 

Değişken x 10'a ayarlandı. Ancak x aynı zamanda döngü değişkenidir. Ancak döngü değişkeninin kapsamının for döngü bloğuyla sınırlı olduğunu varsayarız, değil mi?

Çıktıya bakalım:

Output >>>

Squares list: [0, 1, 4, 9, 16]
x after for loop: 4

 

Bunu görüyoruz x artık 4, döngüde aldığı son değer, onu ayarladığımız başlangıç ​​değeri olan 10 değil.

Şimdi for döngüsünü bir anlama ifadesi ile değiştirirsek ne olacağını görelim:

x = 10
squares = [x ** 2 for x in range(5)]

print("Squares list:", squares)  

# x is 10 here
print("x after list comprehension:", x)

 

Burada, x 10, anlama ifadesinden önce ayarladığımız değer:

Output >>>

Squares list: [0, 1, 4, 9, 16]
x after list comprehension: 10

Nasıl Kaçınılır?

Beklenmedik davranışlardan kaçınmak için: Döngü kullanıyorsanız, döngü değişkenine daha sonra erişmek istediğiniz başka bir değişkenle aynı adı vermediğinizden emin olun.

Python'da şunu kullanıyoruz: is Nesne kimliğini kontrol etmek için kullanılan anahtar kelime. Yani iki değişkenin bellekteki aynı nesneye başvurup başvurmadığını kontrol eder. Eşitliği kontrol etmek için şunu kullanırız: == Şebeke. Evet?

Şimdi bir Python REPL başlatın ve aşağıdaki kodu çalıştırın:

>>> a = 7
>>> b = 7
>>> a == 7
True
>>> a is b
True

 

Şimdi şunu çalıştırın:

>>> x = 280
>>> y = 280
>>> x == y
True
>>> x is y
False

 

Durun, bu neden oluyor? Bunun nedeni, Python'un standart uygulaması olan CPython'daki "tamsayı önbelleğe alma" veya "araya yerleştirme"dir.

CPython tamsayı nesneleri önbelleğe alır -5 ila 256 aralığında. Bu, bu aralıktaki bir tamsayıyı her kullandığınızda Python'un bellekte aynı nesneyi kullanacağı anlamına gelir. Bu nedenle, bu aralıktaki iki tam sayıyı aşağıdakileri kullanarak karşılaştırdığınızda: is anahtar kelime, sonuç True çünkü bellekteki aynı nesneye bakın.

Bu yüzden a is b İade True. Bunu çıktı alarak da doğrulayabilirsiniz. id(a) ve id(b).

Ancak bu aralığın dışındaki tamsayılar önbelleğe alınmaz. Ve bu tür tam sayıların her ortaya çıkışı bellekte yeni bir nesne yaratır. 

Dolayısıyla, önbelleğe alınmış aralığın dışındaki iki tam sayıyı aşağıdakileri kullanarak karşılaştırdığınızda: is anahtar kelime (evet, x ve y örneğimizde her ikisi de 280'e ayarlanmış), sonuç False çünkü bunlar aslında hafızadaki iki farklı nesnedir.

Nasıl Kaçınılır?

kullanmayı denemediğiniz sürece bu davranış bir sorun olmamalıdır. is iki nesnenin eşitliğini karşılaştırmak için. Bu yüzden her zaman şunu kullanın: == Herhangi iki Python nesnesinin aynı değere sahip olup olmadığını kontrol etmek için operatör.

Python'daki yerleşik veri yapılarına aşina iseniz tuple'ların değişmez. Yani sen yapamam bunları yerinde değiştirin. Listeler ve sözlükler gibi veri yapıları ise değişken. seni kastediyorum yapabilmek onları yerinde değiştirin.

Peki ya bir veya daha fazla değiştirilebilir nesne içeren demetler ne olacak?

Bir Python REPL başlatmak ve şu basit örneği çalıştırmak yararlı olacaktır:

>>> my_tuple = ([1,2],3,4)
>>> my_tuple[0].append(3)
>>> my_tuple
([1, 2, 3], 3, 4)

 

Burada tuple'ın ilk elemanı iki elemanlı bir listedir. İlk listeye 3 eklemeyi denedik ve gayet iyi çalışıyor! Peki, az önce bir tuple'ı yerinde değiştirdik mi?

Şimdi listeye iki öğe daha eklemeye çalışalım, ancak bu sefer += operatörünü kullanarak:

>>> my_tuple[0] += [4,5]
Traceback (most recent call last):
  File "", line 1, in 
TypeError: 'tuple' object does not support item assignment

 

Evet, tuple nesnesinin öğe atamasını desteklemediğini belirten bir TypeError alıyorsunuz. Bu bekleniyor. Ama hadi tuple'ı kontrol edelim: 

>>> my_tuple
([1, 2, 3, 4, 5], 3, 4)

 

Listeye 4. ve 5. elementlerin eklendiğini görüyoruz! Program hem hata verip hem de başarılı mı oldu?

+= operatörü dahili olarak şunu çağırarak çalışır: __iadd__() Yerinde ekleme gerçekleştiren ve listeyi yerinde değiştiren yöntem. Atama bir TypeError istisnası oluşturur, ancak öğelerin listenin sonuna eklenmesi zaten başarılı olmuştur. += belki de en keskin köşedir!

Nasıl Kaçınılır?

Programınızda bu tür tuhaflıklardan kaçınmak için tuple'ları kullanmayı deneyin. bir tek değişmez koleksiyonlar için. Ve değiştirilebilir nesneleri mümkün olduğunca demet öğeleri olarak kullanmaktan kaçının.

Değişkenlik şu ana kadar tartışmamızda yinelenen bir konuydu. İşte bu öğreticiyi tamamlamak için başka bir tane daha.

Bazen listelerin bağımsız kopyalarını oluşturmanız gerekebilir. Ancak buna benzer bir sözdizimi kullanarak bir kopya oluşturduğunuzda ne olur? list2 = list1 nerede list1 orijinal liste mi?

Bu, oluşturulan sığ bir kopyadır. Bu nedenle yalnızca listenin orijinal öğelerine yapılan referansları kopyalar. Sığ kopya yoluyla öğeleri değiştirmek, her ikisi de orijinal liste ve sığ kopya. 

Bu örneği ele alalım:

original_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

# Shallow copy of the original list
shallow_copy = original_list

# Modify the shallow copy
shallow_copy[0][0] = 100

# Print both the lists
print("Original List:", original_list)
print("Shallow Copy:", shallow_copy)

 

Sığ kopyada yapılan değişikliklerin orijinal listeyi de etkilediğini görüyoruz:

Output >>>

Original List: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]
Shallow Copy: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]

 

Burada sığ kopyadaki ilk iç içe listenin ilk elemanını değiştiriyoruz: shallow_copy[0][0] = 100. Ancak değişikliğin hem orijinal listeyi hem de yüzeysel kopyayı etkilediğini görüyoruz. 

Nasıl Kaçınılır?

Bunu önlemek için şu şekilde derin bir kopya oluşturabilirsiniz:

import copy

original_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

# Deep copy of the original list
deep_copy = copy.deepcopy(original_list)

# Modify an element of the deep copy
deep_copy[0][0] = 100

# Print both lists
print("Original List:", original_list)
print("Deep Copy:", deep_copy)

 

Artık derin kopyada yapılacak herhangi bir değişiklik orijinal listeyi değiştirmeden bırakır.

Output >>>

Original List: [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Deep Copy: [[100, 2, 3], [4, 5, 6], [7, 8, 9]]

Ve bu bir sarma! Bu derste Python'daki çeşitli tuhaflıkları araştırdık: değişken varsayılanların şaşırtıcı davranışlarından yüzeysel kopyalama listelerinin inceliklerine kadar. Bu yalnızca Python'un tuhaflıklarına bir giriş niteliğindedir ve hiçbir şekilde kapsamlı bir liste değildir. Tüm kod örneklerini bulabilirsiniz GitHub'da.

Python'da daha uzun süre kod yazmaya devam ettikçe ve dili daha iyi anladıkça, belki bunlardan çok daha fazlasıyla karşılaşacaksınız. O halde kodlamaya devam edin, keşfetmeye devam edin!

Bu eğitimin devamını okumak isterseniz yorumlarınızda bize bildirin.
 
 

Bala Priya C Hindistan'dan bir geliştirici ve teknik yazardır. Matematik, programlama, veri bilimi ve içerik oluşturmanın kesiştiği noktada çalışmayı seviyor. İlgi ve uzmanlık alanları DevOps, veri bilimi ve doğal dil işlemeyi içermektedir. Okumayı, yazmayı, kodlamayı ve kahve içmeyi seviyor! Şu anda öğreticiler, nasıl yapılır kılavuzları, fikir yazıları ve daha fazlasını yazarak öğrenmeye ve bilgilerini geliştirici topluluğuyla paylaşmaya çalışıyor. Bala ayrıca ilgi çekici kaynaklara genel bakış ve kodlama eğitimleri de oluşturuyor.

spot_img

En Son İstihbarat

spot_img