প্রত্যাবর্তন, প্রত্যাবর্তন কিছুই না, এবং কোনও রিটার্নও নেই?


386

তিনটি ফাংশন বিবেচনা করুন:

def my_func1():
  print "Hello World"
  return None

def my_func2():
  print "Hello World"
  return

def my_func3():
  print "Hello World"

তারা প্রত্যেকেই কারও কাছে ফিরে আসে না। এই ফাংশনগুলির প্রত্যাশিত মানটি কীভাবে আচরণ করে তার মধ্যে কোনও পার্থক্য রয়েছে? একে অপরের তুলনায় পছন্দ করার কোনও কারণ আছে কি?


40
নোট করুন যে একটি শৈলীগত পার্থক্য আছে। return Noneআমার কাছে ইঙ্গিত দেয় যে ফাংশনটির মাঝে মাঝে একটি Noneফেরত না দেওয়া মান থাকে, তবে এর অবস্থানটিতে এই return Noneজাতীয় রিটার্নের মান নেই। না লিখতে মোটেও returnবোঝা যায় না যে "ফাংশন" এর বিপরীতে কোনও "পদ্ধতি" এর মতো আকর্ষণীয় রিটার্ন মান কখনও হয় না। returnপূর্ববর্তী পয়েন্ট অনুসারে একটি "পদ্ধতি" থেকে প্রাথমিকভাবে উপস্থিত হওয়া বোঝায়।

উত্তর:


500

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

ব্যবহার return None

এটি বলে যে ফাংশনটি প্রকৃতপক্ষে পরবর্তী ব্যবহারের জন্য কোনও মান ফেরত বোঝাতে হয় এবং এই ক্ষেত্রে এটি ফিরে আসে None। এই মানটি Noneঅন্য কোথাও ব্যবহার করা যেতে পারে। return Noneফাংশন থেকে অন্য কোনও সম্ভাব্য রিটার্ন মান না থাকলে কখনই ব্যবহার করা হয় না।

নিম্নলিখিত উদাহরণে, personপ্রদত্তটি motherযদি personকোনও মানুষ হয় তবে আমরা ফিরে আসি। যদি এটি কোনও মানুষ না হয় তবে আমরা ফিরে Noneআসি যেহেতু এর personএকটি নেই mother(আসুন ধরা যাক এটি কোনও প্রাণী বা কিছু নয়)।

def get_mother(person):
    if is_human(person):
        return person.mother
    else:
        return None

ব্যবহার return

এটি breakলুপগুলির মতো একই কারণে ব্যবহৃত হয়। রিটার্ন মানটি কোনও ব্যাপার নয় এবং আপনি কেবল পুরো ফাংশন থেকে প্রস্থান করতে চান। আপনার এটির প্রায়শই প্রয়োজন হয় না সত্ত্বেও এটি কিছু জায়গায় এটি অত্যন্ত কার্যকর।

আমরা 15 পেয়েছি prisonersএবং আমরা জানি যে তাদের একটির কাছে ছুরি রয়েছে। আমরা তাদের প্রত্যেকের কাছ prisonerথেকে ছুরি আছে কিনা তা পরীক্ষা করে লুপ করি । যদি আমরা সেই ব্যক্তিকে একটি ছুরি দিয়ে আঘাত করি তবে আমরা কেবলমাত্র ফাংশনটি থেকে বেরিয়ে যেতে পারি কারণ আমরা জানি যে কেবল একটি ছুরি আছে এবং চেক বাকী কোনও কারণ নেই prisoners। যদি আমরা prisonerএকটি ছুরি সহ এটি না পাই তবে আমরা একটি সতর্কতা বাড়িয়ে তুলি। এটি বিভিন্ন উপায়ে করা যেতে পারে এবং ব্যবহার returnকরা সম্ভবত সর্বোত্তম উপায় নয়, তবে returnকোনও ফাংশন থেকে বেরিয়ে আসার জন্য কীভাবে ব্যবহার করতে হয় তা প্রদর্শন করার জন্য এটি কেবল উদাহরণ ।

def find_prisoner_with_knife(prisoners):
    for prisoner in prisoners:
        if "knife" in prisoner.items:
            prisoner.move_to_inquisition()
            return # no need to check rest of the prisoners nor raise an alert
    raise_alert()

দ্রষ্টব্য: আপনার কখনই করা উচিত নয় var = find_prisoner_with_knife(), যেহেতু ফেরতের মান ধরা হয় না।

কোন ব্যবহার returnএ সব

এটিও ফিরে আসবে None, তবে সেই মানটি ব্যবহার বা ধরা বোঝাতে নয়। এর সহজ অর্থ হল যে ফাংশনটি সফলভাবে শেষ হয়েছে। এটি মূলত হিসাবে একই returnমধ্যে voidযেমন সি ++ বা জাভা যেমন ভাষায় ফাংশন।

নিম্নলিখিত উদাহরণে, আমরা ব্যক্তির মায়ের নাম সেট করি এবং তারপরে সফলতার সাথে সমাপ্তির পরে ফাংশনটি বের হয়।

def set_mother(person, mother):
    if is_human(person):
        person.mother = mother

দ্রষ্টব্য: আপনার কখনই করা উচিত নয় var = set_mother(my_person, my_mother), যেহেতু ফেরতের মান ধরা হয় না।


5
var = get_mother()আপনি যদি varঅন্য ক্রিয়াকলাপগুলিতে যাচ্ছেন যা ঠিক আছে None- তবে "কখনই" কিছুটা চরম হয় না
joelb

যদি var = get_mother()ব্যবহার না করা যায় তবে কীভাবে রিটার্নের মান গ্রহণ করা উচিত ? আইএমএইচও এটি করা সম্পূর্ণ জরিমানা। আপনার এটি ব্যবহার Noneকরার if varআগে কোনও অমূল্য পরীক্ষা করা উচিত তা নিশ্চিত করা দরকার ।
উইঙ্কলারr

আমি মনে করি এটি উল্লেখ করা গুরুত্বপূর্ণ যে এটি কেবল একটি ভাল সম্মেলন নয়, এটি পিইপি 8 দ্বারা প্রয়োজনীয়। আমি আপনার প্রশংসা করার জন্য একটি উত্তর পোস্ট করি এবং এটিতে পিইপি 8 উদ্ধৃত করছি।
ফাবিয়ানো

29

হ্যাঁ, তারা সব একই।

তারা সবাই ঠিক একই জিনিস করছে তা নিশ্চিত করার জন্য আমরা ব্যাখ্যামূলক মেশিন কোড পর্যালোচনা করতে পারি।

import dis

def f1():
  print "Hello World"
  return None

def f2():
  print "Hello World"
  return

def f3():
  print "Hello World"

dis.dis(f1)
    4   0 LOAD_CONST    1 ('Hello World')
        3 PRINT_ITEM
        4 PRINT_NEWLINE

    5   5 LOAD_CONST    0 (None)
        8 RETURN_VALUE

dis.dis(f2)
    9   0 LOAD_CONST    1 ('Hello World')
        3 PRINT_ITEM
        4 PRINT_NEWLINE

    10  5 LOAD_CONST    0 (None)
        8 RETURN_VALUE

dis.dis(f3)
    14  0 LOAD_CONST    1 ('Hello World')
        3 PRINT_ITEM
        4 PRINT_NEWLINE            
        5 LOAD_CONST    0 (None)
        8 RETURN_VALUE      

4
সাবধান এখানে ... dis.disফেরত None:
-এক্স

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

তারা যেভাবেই ঠিক একই নিবন্ধগুলি ব্যবহার করছে কিনা তা অপ্রাসঙ্গিক, সুতরাং আমি আমার কোডটি পরিবর্তন করেছি যাতে আমরা কেবল মেশিন কোডটি কিছুটা বোকা স্ট্রিং তুলনা না করে এখন চোখের পাতায় দেখছি। খুব বড় মাথা আপ জন্য ধন্যবাদ।
ডেভিড মার্কস

19

তারা প্রত্যেকে একই সিঙ্গলটন ফেরত দেয় None- কার্যকরী কোনও পার্থক্য নেই।

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

পাইথনগুলিতে প্রায়শই ফাংশনগুলি সি-তে ফাংশনের Noneমতো ব্যবহৃত হয় void- তাদের উদ্দেশ্য সাধারণত স্থানে ইনপুট আর্গুমেন্টগুলি পরিচালনা করা হয় (যদি না আপনি বিশ্বব্যাপী ডেটা ( শড্ডার ) ব্যবহার করেন )। প্রত্যাবর্তন Noneসাধারণত এটি আরও স্পষ্ট করে তোলে যে আর্গুমেন্টগুলি পরিবর্তন করা হয়েছিল। এটি return"ভাষা সম্মেলন" দৃষ্টিকোণ থেকে বিবৃতিটি ছেড়ে দেওয়া কেন বোধগম্য তা কিছুটা স্পষ্ট করে তোলে ।

এটি বলেছে, আপনি যদি এমন কোনও কোড বেসে কাজ করছেন যা ইতিমধ্যে এই বিষয়গুলির পূর্বনির্ধারিত কনভেনশন রয়েছে তবে আমি অবশ্যই কোড বেসটি অভিন্ন রাখতে সহায়তা করার জন্য মামলাটি অনুসরণ করব ...


1
বা আরও সাধারণভাবে, যে কোনও সময় কোনও returnবিবৃতি আঘাত না করে কোনও ফাংশন শেষ হলে তা ফিরে আসে None

ফাংশনটি কোনও মান ফেরত প্রত্যাশিত হলে রিটার্নের বিবৃতি বাদ দেওয়া মূখ্য নয়। কেবলমাত্র পার্শ্ব প্রতিক্রিয়াগুলির মাধ্যমে পরিচালিত ফাংশনগুলির রিটার্নের বিবৃতি বাদ দেওয়া উচিত should
অণু

@ অণু - হ্যাঁ, আমি মনে করি যে এখানে আমার ব্যাখ্যাটিতে সম্ভবত আমি সেরা কাজটি করতে পারি নি। আমি উপরের (আরও ভাল) উত্তরের সম্পূর্ণ ক্লোন তৈরি না করেই এটি আপডেট করার চেষ্টা করেছি। আমি এখনও এই পোস্টে খুব বেশি খুশি নই ... আমার একাংশ এটি মুছে ফেলতে চায় (যেহেতু উপরের উত্তরটি এত ভাল)) এবং আমার অংশটি এটি রাখতে চাইছে - 9 জন এখনও পর্যন্ত ভেবেছেন এটি ভাল ছিল একটি কারণ বা অন্য। আমি অন্য কারও হাতছাড়া হতে পারে?
মিগিলসন

1
@ জ্যাব - আমি মনে করি এটি সম্ভব নয়। পাইথনে আমি বানরকে যেকোন কিছু দিয়েও প্যাচ করতে পারি (এটি ডিজাইনের মাধ্যমে এবং খুব কম ব্যবহার করা হলে এটি দুর্দান্ত বৈশিষ্ট্য)। বিশেষত, আমি এমন একটি ফাংশন বানর-প্যাচ করতে পারি যা এর সাথে ফিরে আসে না। সমস্ত "এক্সপ্রেশন নয়" চেকগুলি পার্স সময়ে ঘটে থাকে তবে বানর-প্যাচিংয়ের কারণে রানটাইম পর্যন্ত এটি ঘটতে পারে নি। আইওউ, এটি সম্পূর্ণ আলাদা। ব্যক্তিগতভাবে, আমি মনে করি যে বর্তমান আচরণটি বেশ যুক্তিসঙ্গত (এবং অন্যান্য উচ্চ-স্তরের ভাষার সাথে সামঞ্জস্যপূর্ণ) তবে আমি আপনাকে বোঝাতে চাই না :-)।
মিগিলসন

1
@ জ্যাব - উভয়ই Rubyএবং Javascriptপাইথনের মতো একই পদ্ধতি গ্রহণ করুন। আমি নিশ্চিত যে আছি হয় বলে "অকার্যকর" অভিব্যক্তি উচ্চ স্তরের ভাষা উদাহরণ কিন্তু আমি মুহূর্ত (হয়তো যদি আপনি বিবেচনা যে কোনো মনে করতে পারেন না Javaএকটি উচ্চ পর্যায়ের ভাষা) ... কীভাবে বানর-প্যাচিং একটি ফাংশন (যা অন্যান্য বিষয়গুলির মধ্যে পরীক্ষায় বিদ্রূপের জন্য দরকারী) একটি অনুমানের পৃথিবীতে কাজ করে যেখানে পাইথন একটি voidকীওয়ার্ড পেয়েছিল যা এটি তৈরি করে যাতে ফাংশনটি কিছুই ফেরত না? (এছাড়াও, যেমনটি আমি আগে বলেছি, আপনি আমাকে বোঝানোর দরকার নেই যে এটি একটি খারাপ নকশা
you're

4

অন্যরা যেমন উত্তর দিয়েছে, ফলাফলটি হুবহু একই রকম, Noneসব ক্ষেত্রেই ফিরে আসে।

পার্থক্যটি স্টাইলিস্টিক, তবে দয়া করে নোট করুন যে পিইপি 8 এর ব্যবহারের সাথে সামঞ্জস্যতা থাকতে হবে:

রিটার্নের বিবৃতিতে সামঞ্জস্য বজায় রাখুন। হয় কোনও ফাংশনে সমস্ত রিটার্নের বিবৃতিতে একটি অভিব্যক্তি ফিরে পাওয়া উচিত, বা তাদের কোনওটিরও উচিত নয়। যদি কোনও রিটার্ন স্টেটমেন্ট কোনও অভিব্যক্তি দেয়, যে কোনও রিটার্ন স্টেটমেন্ট যেখানে কোনও মূল্য ফেরত পাওয়া যায় না তা এটিকে স্পষ্টভাবে রিটার্ন হিসাবে উল্লেখ করা উচিত এবং কোনও স্পষ্ট রিটার্ন বিবৃতি ফাংশনের শেষে উপস্থিত থাকতে হবে (যদি পৌঁছতে পারে))

হ্যাঁ:

def foo(x):
    if x >= 0:
        return math.sqrt(x)
    else:
        return None

def bar(x):
    if x < 0:
        return None
    return math.sqrt(x)

নং:

def foo(x):
    if x >= 0:
        return math.sqrt(x)

def bar(x):
    if x < 0:
        return
    return math.sqrt(x)

https://www.python.org/dev/peps/pep-0008/#programming-recommendations


মূলত, যদি আপনি Noneকোনও ফাংশনে অ- মানটি ফিরিয়ে দেন তবে এর অর্থ ফেরতের মানটির অর্থ রয়েছে এবং এটি কলকারীদের দ্বারা ধরা পড়ে। সুতরাং যখন আপনি ফিরে আসবেন None, এটি অবশ্যই স্পষ্ট হতে হবে, Noneএই ক্ষেত্রে বোঝাতে গেলে এর অর্থ রয়েছে, এটি সম্ভাব্য প্রত্যাবর্তন মানগুলির মধ্যে একটি।

আপনার যদি মোটেও ফেরতের প্রয়োজন না হয় তবে আপনি মূলত ফাংশনের পরিবর্তে একটি প্রক্রিয়া হিসাবে কাজ করেন, তাই কেবল returnবিবৃতিটি অন্তর্ভুক্ত করবেন না ।

যদি আপনি কোনও প্রক্রিয়া জাতীয় ফাংশন লিখছেন এবং আগে ফিরে আসার সুযোগ রয়েছে (যেমন আপনি ইতিমধ্যে ইতিমধ্যে সম্পন্ন হয়ে গিয়েছেন এবং বাকি ফাংশনটি কার্যকর করার প্রয়োজন নেই) আপনি returnপাঠকের জন্য সিগন্যাল করার জন্য খালি এস ব্যবহার করতে পারেন এটি কেবলমাত্র মৃত্যুদন্ড কার্যকর করার এক প্রাথমিক সমাপ্তি এবং Noneপ্রত্যাবর্তিত মানটির স্পষ্টভাবে অর্থ হয় না এবং এটি ধরা পড়ার অর্থ নয় (পদ্ধতিটির মতো ফাংশন সর্বদা Noneযাইহোক ফিরে আসে )।


3

কার্যকারিতার দিক থেকে এগুলি সমস্ত এক, তাদের মধ্যে পার্থক্য কোড পাঠযোগ্যতা এবং শৈলীতে (যা বিবেচনা করা গুরুত্বপূর্ণ)

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