जवाबों:
PEP-8 में अनुशंसा आप में चल रहे हैं:
हमेशा एक असाइनमेंट स्टेटमेंट के बजाय एक डिफ स्टेटमेंट का उपयोग करें जो एक नाम के लिए सीधे लंबोदर अभिव्यक्ति को बांधता है।
हाँ:
def f(x): return 2*x
नहीं:
f = lambda x: 2*x
पहले रूप का मतलब है कि परिणामी फ़ंक्शन ऑब्जेक्ट का नाम विशेष रूप से जेनेरिक '<lambda>' के बजाय 'f' है। यह सामान्य रूप से ट्रेसबैक और स्ट्रिंग अभ्यावेदन के लिए अधिक उपयोगी है। असाइनमेंट स्टेटमेंट का उपयोग एकमात्र लाभ को समाप्त करता है एक लैम्ब्डा अभिव्यक्ति एक स्पष्ट डीफ़ स्टेटमेंट (यानी कि यह एक बड़ी अभिव्यक्ति के अंदर एम्बेड किया जा सकता है) पर पेश कर सकता है
नाम के लिए लंबोदर को सौंपना मूल रूप से सिर्फ def
- और सामान्य रूप से कार्यक्षमता को डुप्लिकेट करता है , भ्रम से बचने और स्पष्टता बढ़ाने के लिए कुछ एक ही तरीका करना सबसे अच्छा है।
लैम्ब्डा के लिए वैध उपयोग का मामला वह है जहाँ आप बिना असाइन किए किसी फ़ंक्शन का उपयोग करना चाहते हैं, जैसे:
sorted(players, key=lambda player: player.rank)
सामान्य तौर पर, ऐसा करने के खिलाफ मुख्य तर्क यह है कि def
बयानों के परिणामस्वरूप कोड की अधिक लाइनें होंगी। उस पर मेरी मुख्य प्रतिक्रिया होगी: हाँ, और यह ठीक है। जब तक आप कोड गोल्फिंग नहीं कर रहे हैं, लाइनों की संख्या को कम करना कुछ ऐसा नहीं है जो आपको करना चाहिए: लघु पर स्पष्ट के लिए जाएं।
def
PEP8 चेकर के माध्यम से उपयोग करने के सुझाए गए दृष्टिकोण को चलाने पर , आपको मिलता है E704 multiple statements on one line (def)
, और यदि आप इसे दो पंक्तियों में विभाजित करते हैं , तो आपको E301 expected 1 blank line, found 0
: - /
यहाँ कहानी है, मेरे पास एक साधारण मेमने का कार्य था जिसे मैं दो बार उपयोग कर रहा था।
a = map(lambda x : x + offset, simple_list)
b = map(lambda x : x + offset, another_simple_list)
यह सिर्फ प्रतिनिधित्व के लिए है, मुझे इसके विभिन्न संस्करणों में से कुछ का सामना करना पड़ा है।
अब, DRY चीजों को रखने के लिए, मैं इस आम मेमने का पुन: उपयोग करना शुरू करता हूं।
f = lambda x : x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
इस बिंदु पर मेरे कोड क्वालिटी चेकर को लैम्ब्डा के नामांकित फ़ंक्शन के बारे में शिकायत है, इसलिए मैं इसे एक फ़ंक्शन में परिवर्तित करता हूं।
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
अब चेकर शिकायत करता है कि एक फ़ंक्शन को पहले और बाद में एक रिक्त लाइन द्वारा बाध्य किया जाना है।
def f(x):
return x + offset
a = map(f, simple_list)
b = map(f, another_simple_list)
यहां अब हमारे पास मूल 2 लाइनों के बजाय कोड की 6 पंक्तियां हैं, जिनमें पठनीयता में कोई वृद्धि नहीं है और न ही पायथोनिक होने में कोई वृद्धि है। इस बिंदु पर कोड चेकर को कार्य के बारे में शिकायत होती है कि उसके पास डॉकस्ट्रिंग नहीं है।
मेरे विचार में इस नियम को बेहतर तरीके से टाला और तोड़ा जाता है जब यह समझ में आता है, अपने फैसले का उपयोग करें।
a = [x + offset for x in simple_list]
। कोई जरूरत नहीं है map
और lambda
यहाँ का उपयोग करने के लिए ।
x + offset
को एक अमूर्त स्थान पर स्थानांतरित करना था जिसे कोड की एक से अधिक लाइन को बदले बिना अपडेट किया जा सकता है। जैसा कि आपने उल्लेख किया है, सूची बोध के साथ, आपको अभी भी कोड की दो पंक्तियों की आवश्यकता होगी जो निहित हैं x + offset
वे अभी सूची समझ में होंगे। जैसा कि लेखक चाहते थे, उन्हें बाहर खींचने के लिए आपको def
या की आवश्यकता होगी lambda
।
def
और lambda
एक भी functionalools.partial का उपयोग कर सकता है : f = partial(operator.add, offset)
और फिर a = list(map(f, simple_list))
।
def f(x): return x + offset
(यानी, एक लाइन पर परिभाषित एक सरल कार्य)? कम से कम flake8 के साथ मुझे रिक्त लाइनों के बारे में शिकायत नहीं मिलती है।
a, b = [[x + offset for x lst] for lst in (simple_list, another_simple_list)]
लेटवेयर पूरी तरह से सही है: मूल रूप से PEP-8 चाहता है कि आप चीजों से बचें
f = lambda x: 2 * x
और इसके बजाय उपयोग करें
def f(x):
return 2 * x
हालाँकि, जैसा कि हाल ही के एक बगरेपोर्ट (अगस्त 2014) में दिया गया है, इस तरह के बयान अब निम्नलिखित हैं:
a.f = lambda x: 2 * x
a["f"] = lambda x: 2 * x
चूंकि मेरे PEP-8 चेकर इसे अभी तक सही तरीके से लागू नहीं करते हैं, इसलिए मैंने E731 को फिलहाल बंद कर दिया।
def
, PEP8 चेकर के साथ शिकायत की जाती है E301 expected 1 blank line, found 0
, इसलिए आपको इसके पहले एक बदसूरत खाली लाइन जोड़ना होगा।
मुझे एक ऐसी स्थिति का भी सामना करना पड़ा जिसमें एक डिफ (ined) फ़ंक्शन का उपयोग करना असंभव था।
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},
}
इस मामले में, मैं वास्तव में एक मैपिंग करना चाहता था जो वर्ग से संबंधित हो। मानचित्रण में कुछ वस्तुओं को समान कार्य की आवश्यकता होती है। कक्षा के बाहर नामांकित समारोह रखना अशुभ होगा। मुझे क्लास बॉडी के अंदर से किसी विधि (staticmethod, classmethod या normal) को संदर्भित करने का कोई तरीका नहीं मिला है। कोड चलने पर SomeClass अभी तक मौजूद नहीं है। इसलिए कक्षा से इसका जिक्र संभव नहीं है।
also_not_reachable
मैपिंग परिभाषा में उल्लेख कर सकते हैंSomeClass.also_not_reachable
f
मेरे लिए 2.7 और 3.5 दोनों में समान है
@staticmethod
और @classmethod
एक वस्तु की जरूरत नहीं है, बस SomeClass.also_not_reachable
(हालांकि वे विशिष्ट नामों की आवश्यकता)। यदि आपको उन्हें कक्षा के तरीकों से उपयोग करने की आवश्यकता हैself.also_not_reachable
*not_reachable
तरीकों का नाम बदलकर not_as_easily_reachable_from_class_definition_as_a_lambda
xD
flake8
( flake8.pycqa.org )