E731 একটি ল্যাম্বডা এক্সপ্রেশন বরাদ্দ করবেন না, একটি ডিএফ ব্যবহার করুন


193

আমি যখনই ল্যাম্বদা এক্সপ্রেশন ব্যবহার করি তখনই আমি এই পেপ 8 সতর্কতাটি পাই। লাম্বদা এক্সপ্রেশন প্রস্তাবিত হয় না? না হলে কেন?


4
স্পষ্টতার জন্য, প্রশ্নটি একটি স্বয়ংক্রিয় চেক ইন flake8( flake8.pycqa.org )
রেকলাইস

উত্তর:


230

আপনি যে পিইপি -8 এ যাচ্ছেন তার মধ্যে সুপারিশটি হ'ল:

সর্বদা একটি অ্যাসাইনমেন্ট স্টেটমেন্টের পরিবর্তে একটি ডিফ স্টেটমেন্ট ব্যবহার করুন যা ল্যাম্বডা এক্সপ্রেশনটি সরাসরি একটি নামের সাথে আবদ্ধ করে।

হ্যাঁ:

def f(x): return 2*x 

নং:

f = lambda x: 2*x 

প্রথম ফর্মটির অর্থ হ'ল ফলস্বরূপ ফাংশন অবজেক্টের নামটি জেনেরিকের পরিবর্তে 'f' হয় 'ল্লেম্বদা>'। এটি সাধারণভাবে ট্রেসব্যাক এবং স্ট্রিং উপস্থাপনার জন্য আরও কার্যকর। অ্যাসাইনমেন্ট স্টেটমেন্টের ব্যবহারটি ল্যাম্বডা এক্সপ্রেশনটি সুস্পষ্ট ডিফ স্টেটমেন্টের (যেমন এটি বৃহত্তর এক্সপ্রেশনের অভ্যন্তরে এম্বেড করা যেতে পারে) প্রস্তাব করতে পারে এমন একমাত্র উপকারটি সরিয়ে দেয়

ল্যাম্বডাস নামগুলিতে অর্পণ করা মূলত এর কার্যকারিতাটির নকল করে def- এবং সাধারণভাবে, বিভ্রান্তি এড়াতে এবং স্বচ্ছতা বাড়াতে এককভাবে কিছু করা ভাল।

ল্যাম্বডা-র বৈধ ব্যবহারের ক্ষেত্রটি হল আপনি যেখানে কোনও কাজ নির্দিষ্ট করে না দিয়ে ব্যবহার করতে চান, যেমন:

sorted(players, key=lambda player: player.rank)

সাধারণভাবে, এটি করার বিরুদ্ধে প্রধান যুক্তি হ'ল defবিবৃতিগুলি কোডের আরও লাইন তৈরি করবে। সে সম্পর্কে আমার মূল প্রতিক্রিয়া হবে: হ্যাঁ, এবং এটি ঠিক আছে। আপনি কোড গল্ফিং না করলে লাইনের সংখ্যা হ্রাস করা আপনার করা উচিত নয়: সংক্ষেপে পরিষ্কার হয়ে যান।


5
আমি দেখতে পাচ্ছি না যে এটি আরও খারাপ কি না। ট্রেসব্যাকটি এখনও ত্রুটিযুক্ত লাইন নম্বর এবং উত্স ফাইল অন্তর্ভুক্ত করতে চলেছে। একটি "চ" বলতে পারে অন্যটি "ল্যাম্বদা" বলে। সম্ভবত ল্যাম্বডা ত্রুটিটি স্ক্যান করা সহজ কারণ এটি কোনও একক-চরিত্রের ফাংশন নাম নয়, বা একটি নাম খারাপ নামকরণ করা হয়নি?
g33kz0r

4
@ g33kz0r ঠিক আছে, নিশ্চিত, আপনি যদি ধরে নেন যে আপনার কোডটির বাকী কোডগুলি নিম্নমানের হয়ে চলেছে, নিম্নলিখিত কনভেনশনগুলি আপনাকে বেশি লাভ করতে পারে না। সাধারণভাবে, না, এটি বিশ্বের শেষ নয়, তবে এটি এখনও একটি খারাপ ধারণা।
গ্যারেথ লেটি

39
এই উত্তরটি খুব সহায়ক নয়, কারণ defপিইপি 8 চেকারের মাধ্যমে ব্যবহারের প্রস্তাবিত পদ্ধতির চলাকালীন , আপনি পেয়ে যাবেন E704 multiple statements on one line (def)এবং আপনি যদি দুটি লাইনে বিভক্ত হন তবে আপনি পাবেন E301 expected 1 blank line, found 0: - /
অ্যাডাম স্পায়ার্স

4
আমি একমত যে এটি বিভক্ত করা উচিত। আমার বক্তব্যগুলি হ'ল ক) উপরের উত্তরের কোডে এটি বিভক্ত হবে না, কারণ E704, এবং খ) আপনি যদি এটি বিভক্ত করেন তবে E301 এড়াতে আপনার উপরে একটি কুৎসিত ফাঁকা রেখা দরকার।
অ্যাডাম স্পায়ার্স

3
আমি ল্যাম্বডাস ব্যবহার করি যখন আমি কোনও বিশুদ্ধ ফাংশন (কোনও পার্শ্ব প্রতিক্রিয়া নয়) জোর দিতে চাই এবং কখনও কখনও আমাকে একই ফাংশনটি দুটি স্থানে, যেমন গ্রুপবাইতে এবং একসাথে বাছাই করতে হয়। তাই আমি এই সম্মেলনটিকে উপেক্ষা করি।
মানু

119

এখানে গল্পটি রয়েছে, আমার একটি সাধারণ ল্যাম্বডা ফাংশন ছিল যা আমি দুবার ব্যবহার করছিলাম।

a = map(lambda x : x + offset, simple_list)
b = map(lambda x : x + offset, another_simple_list)

এটি কেবল উপস্থাপনের জন্যই, আমি এর বিভিন্ন সংস্করণের বেশ কয়েকটি মুখোমুখি হয়েছি।

এখন জিনিসগুলি শুকনো রাখতে আমি এই সাধারণ ল্যাম্বডাকে পুনরায় ব্যবহার শুরু করি।

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 টি লাইন রয়েছে যার পাঠযোগ্যতা নেই এবং পাইথোনিক হওয়ার কোনও বৃদ্ধি নেই। এই সময়ে কোড চেকার ফাংশনটিতে ডকস্ট্রিং না থাকার বিষয়ে অভিযোগ করে।

আমার মতে এই নিয়মটি আরও ভালভাবে এড়ানো এবং ভাঙা উচিত যখন এটি বোধগম্য হয়, আপনার রায়টি ব্যবহার করুন।


13
a = [x + offset for x in simple_list]। ব্যবহারের কোন প্রয়োজন নেই mapএবং lambdaএখানে।
জর্জি

8
@ জর্জি আমার বিশ্বাস বিন্দুটি ছিল x + offsetঅংশটি একটি বিমূর্ত জায়গায় নিয়ে যাওয়া যা কোডের একাধিক লাইন পরিবর্তন না করে আপডেট করা যায়। আপনি যেমন উল্লেখ করেছেন তেমন তালিকা বোধগম্যতার সাথে আপনার এখনও দুটি লাইনের কোডের প্রয়োজন হবে যা সেগুলিতে রয়েছে x + offsetকেবলমাত্র তালিকার বোধগম্য। এগুলি লেখক যেমনটি চেয়েছিলেন তেমনভাবে টানতে আপনার একটি defবা প্রয়োজন হবে lambda
জুলিয়ান

1
@ জুলিয়ান ছাড়াও defএবং lambdaকেউ ফান্টাকুলগুলি ব্যবহার করতে পারে p পার্টিয়াল : f = partial(operator.add, offset)এবং তারপরে a = list(map(f, simple_list))
জর্জি

সম্পর্কে কি def f(x): return x + offset(অর্থাত, একটি সহজ ফাংশন একটি একক লাইন সংজ্ঞাসমূহ)? কমপক্ষে flake8 দিয়ে আমি ফাঁকা লাইন সম্পর্কে অভিযোগ পাই না।
ডকোক

1
@ জুলিয়ান কিছু ক্ষেত্রে আপনি নেস্টেড বোধগম্যতা ব্যবহার করতে পারেন:a, b = [[x + offset for x lst] for lst in (simple_list, another_simple_list)]
ওয়াজান্দ্রিয়া

24

ল্যাটিওয়্যারটি একেবারে ঠিক: মূলত পিইপি -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

যেহেতু আমার পিইপি -8 পরীক্ষক এটি এখনও সঠিকভাবে প্রয়োগ করে না তাই আপাতত আমি E731 বন্ধ করে দিয়েছি।


8
এমনকি ব্যবহার করার সময় def, পিইপি 8 চেকার অভিযোগ করে E301 expected 1 blank line, found 0, সুতরাং আপনাকে তার আগে একটি কুরুচিপূর্ণ ফাঁকা লাইন যুক্ত করতে হবে।
অ্যাডাম স্পায়ার্স

1

আমি এমন একটি পরিস্থিতির মুখোমুখিও হয়েছিলাম যেখানে ডিফ (ইনড) ফাংশনটি ব্যবহার করা এমনকি অসম্ভবও ছিল।

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},
  }

এই ক্ষেত্রে, আমি সত্যিই ক্লাসের অন্তর্গত একটি ম্যাপিং তৈরি করতে চেয়েছিলাম। ম্যাপিংয়ের কিছু বস্তুর একই ফাংশন প্রয়োজন। ক্লাসের বাইরে নামকরণের কার্যটি রাখা অযৌক্তিক হবে। আমি শ্রেণীর দেহের অভ্যন্তর থেকে কোনও পদ্ধতি (স্ট্যাটিকমেডোথর, শ্রেণীবদ্ধ বা সাধারণ) উল্লেখ করার উপায় খুঁজে পাইনি। কোডটি চালিত হওয়ার পরে সামার ক্লাস এখনও বিদ্যমান নেই। সুতরাং এটি ক্লাস থেকে উল্লেখ করা সম্ভব নয়।


আপনি also_not_reachableম্যাপিং সংজ্ঞাটি হিসাবে উল্লেখ করতে পারেনSomeClass.also_not_reachable
ইয়্যাকজz

1
আমি জানি না আপনি এখানে কী পয়েন্ট বানাতে চাইছেন। আপনার ফাংশনটির প্রতিটি নামই fআমার কাছে 2.7 এবং 3.5 উভয় ক্ষেত্রেই পৌঁছনীয়
এরিক

না, ল্যাম্বডা ফাংশন বাদে সমস্ত ফাংশন ক্লাস বডি থেকে পাওয়া যায় না। আপনি যদি একটি অ্যাট্রিবিউটআরার পেয়ে যাবেন: টাইপ অবজেক্ট 'সোমারস ক্লাস'-এর কোনও বৈশিষ্ট্য নেই' ... 'যদি আপনি কিছু_ম্যাপিং অবজেক্টে function ফাংশনগুলির মধ্যে একটিতে অ্যাক্সেস করার চেষ্টা করেন।
সিএমপি করুন

3
@ সিম্প তাদের সমস্তই নিখুঁত অ্যাক্সেসযোগ্য। যাদের রয়েছে @staticmethodএবং @classmethodতাদের কোনও বস্তুর প্রয়োজন নেই, কেবল SomeClass.also_not_reachable(যদিও তাদের স্বতন্ত্র নাম প্রয়োজন)। আপনার যদি ক্লাসের পদ্ধতিগুলি থেকে এগুলি অ্যাক্সেস করার প্রয়োজন হয় তবে কেবল ব্যবহার করুনself.also_not_reachable
34

@ সিম্প হয়তো আপনার *not_reachableপদ্ধতিগুলির নাম পরিবর্তন করতে হবে not_as_easily_reachable_from_class_definition_as_a_lambdaএক্সডি
রোমেন ভিনসেন্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.