Lambda ifadeleri kullandığımda bu pep8 uyarısını alıyorum. Lambda ifadeleri önerilmez mi? Değilse neden?
Lambda ifadeleri kullandığımda bu pep8 uyarısını alıyorum. Lambda ifadeleri önerilmez mi? Değilse neden?
Yanıtlar:
Karşılaştığınız PEP-8'deki öneri :
Lambda ifadesini doğrudan bir ada bağlayan atama ifadesi yerine her zaman bir def ifadesi kullanın.
Evet:
def f(x): return 2*x
Hayır:
f = lambda x: 2*x
İlk form, sonuçta ortaya çıkan işlev nesnesinin adının, genel '<lambda>' yerine özellikle 'f' olduğu anlamına gelir. Bu, genel olarak izlemeler ve dize gösterimleri için daha kullanışlıdır. Atama ifadesinin kullanımı, bir lambda ifadesinin açık bir def ifadesi üzerinden sunabileceği tek avantajı ortadan kaldırır (yani, daha büyük bir ifadenin içine gömülebilir)
Adlara lambdas atamak temel olarak sadece işlevselliğini çoğaltır def
- ve genel olarak, karışıklığı önlemek ve netliği artırmak için tek bir yol yapmak en iyisidir.
Lambda için yasal kullanım durumu, bir işlevi atamadan kullanmak istediğiniz yerdir, örneğin:
sorted(players, key=lambda player: player.rank)
Genel olarak, bunu yapmamaya yönelik ana argüman, def
ifadelerin daha fazla kod satırına neden olacağıdır. Buna benim ana cevabım: evet, ve bu iyi. Kod golf yapmadığınız sürece, çizgi sayısını en aza indirmek yapmanız gereken bir şey değildir: kısaca netleşin.
def
PEP8 denetleyicisi aracılığıyla önerilen önerilen yaklaşımı çalıştırırken, alırsınız E704 multiple statements on one line (def)
ve iki satıra böldüğünüzde E301 expected 1 blank line, found 0
: - /
İşte hikaye, iki kez kullandığım basit bir lambda fonksiyonum vardı.
a = map(lambda x : x + offset, simple_list)
b = map(lambda x : x + offset, another_simple_list)
Bu sadece temsil için, bunun birkaç farklı versiyonu ile karşılaştım.
Şimdi, şeyleri KURU tutmak için, bu ortak lambda'yı tekrar kullanmaya başlarım.
f = lambda x : x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
Bu noktada benim kod kalite denetleyicisi lambda adlı bir işlev olmaktan şikayet ediyor, bu yüzden bir işleve dönüştürmek.
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
Şimdi denetleyici, bir işlevin önce ve sonra bir satır boşluk ile sınırlandırılması gerektiğinden şikayet ediyor.
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
Burada, okunabilirlikte bir artış ve pitonik olarak bir artış olmadan orijinal 2 satır yerine 6 kod satırımız var. Bu noktada kod denetleyicisi fonksiyonun docstrings'e sahip olmamasından şikayet eder.
Bence bu kural mantıklı olduğunda kaçınılmalı ve kırılmalıdır, kararınızı kullanın.
a = [x + offset for x in simple_list]
. Kullanmaya gerek yok map
ve lambda
burada.
x + offset
birden fazla kod satırı değiştirmeden güncellenebilir soyutlanmış bir yere taşımak olduğuna inanıyorum . Bahsettiğiniz gibi liste kavrayışları ile, x + offset
şimdi liste kavrayışlarında olacaklarını içeren iki kod satırına ihtiyacınız olacaktır. Bunları yazarın istediği gibi çıkarmak için bir def
ya da ihtiyacınız olacaktır lambda
.
def
ve functools.partial : ve sonra lambda
da kullanabilirsiniz . f = partial(operator.add, offset)
a = list(map(f, simple_list))
def f(x): return x + offset
(yani, tek bir satırda tanımlanan basit bir fonksiyon)? En azından flake8 ile boş satırlardan şikayet alamıyorum.
a, b = [[x + offset for x lst] for lst in (simple_list, another_simple_list)]
Lattyware kesinlikle doğru: Temelde PEP-8 gibi şeylerden kaçınmanızı istiyor
f = lambda x: 2 * x
ve bunun yerine kullan
def f(x):
return 2 * x
Ancak, son bir hata raporunda (Ağustos 2014) ele alındığı gibi, aşağıdaki gibi ifadeler artık uyumludur:
a.f = lambda x: 2 * x
a["f"] = lambda x: 2 * x
PEP-8 denetleyicim bunu henüz doğru bir şekilde uygulamadığından şimdilik E731'i kapattım.
def
, PEP8 denetleyicisi şikayetçi olduğundan E301 expected 1 blank line, found 0
, bundan önce çirkin boş bir satır eklemeniz gerekir.
Ayrıca def (ined) işlevini kullanmanın bile imkansız olduğu bir durumla karşılaştım.
class SomeClass(object):
# pep-8 does not allow this
f = lambda x: x + 1 # NOQA
def not_reachable(self, x):
return x + 1
@staticmethod
def also_not_reachable(x):
return x + 1
@classmethod
def also_not_reachable(cls, x):
return x + 1
some_mapping = {
'object1': {'name': "Object 1", 'func': f},
'object2': {'name': "Object 2", 'func': some_other_func},
}
Bu durumda, gerçekten sınıfa ait bir harita yapmak istedim. Eşlemedeki bazı nesnelerin aynı işleve ihtiyacı vardı. Adlandırılmış bir işlevi sınıfın dışına koymak mantıksız olurdu. Sınıf gövdesi içinden bir yönteme (statik yöntem, sınıf yöntemi veya normal) başvurmak için bir yol bulamadım. Kod çalıştırıldığında SomeClass henüz mevcut değil. Yani sınıftan bahsetmek de mümkün değil.
also_not_reachable
Eşleme tanımındaSomeClass.also_not_reachable
f
benim için hem 2.7 hem de 3.5'te olduğu gibi ulaşılabilir
@staticmethod
ve @classmethod
bir nesneye ihtiyaç duymayanlar, sadece SomeClass.also_not_reachable
(farklı isimlere ihtiyaç duysalar da). Onlara sınıf yöntemlerinden erişmeniz gerekiyorsa sadece kullanınself.also_not_reachable
*not_reachable
yöntemlerinizi not_as_easily_reachable_from_class_definition_as_a_lambda
xD olarak değiştirmelisiniz
flake8
( flake8.pycqa.org ) mesajı