কেন বাদে using or` ব্যবহার বাদে সিনট্যাক্স এরিয়ার সৃষ্টি করে না? এটির জন্য কোনও বৈধ ব্যবহার আছে?


11

কর্মক্ষেত্রে, আমি exceptএকটি orঅপারেটরের সাথে একটি ধারাতে হোঁচট খেয়েছি:

try:
    # Do something.
except IndexError or KeyError:
    # ErrorHandling

আমি জানি যে ব্যতিক্রম ক্লাসগুলি একটি টিউপল হিসাবে পাস করা উচিত, তবে এটি আমাকে তাগিদে দেয় যে এটি এমনকি একটির কারণও হয় না SyntaxError

সুতরাং প্রথমে আমি অনুসন্ধান করতে চেয়েছিলাম এটি আসলে কাজ করে কিনা। এবং এটা না।

>>> def with_or_raise(exc):
...     try:
...         raise exc()
...     except IndexError or KeyError:
...         print('Got ya!')
...

>>> with_or_raise(IndexError)
Got ya!

>>> with_or_raise(KeyError)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in with_or_raise
KeyError

সুতরাং এটি দ্বিতীয় ব্যতিক্রমটি ধরেনি, এবং বাইটকোডের দিকে তাকালে এটি স্পষ্ট হয়ে যায় কেন:

>>> import dis
>>> dis.dis(with_or_raise)
  2           0 SETUP_EXCEPT            10 (to 12)

  3           2 LOAD_FAST                0 (exc)
              4 CALL_FUNCTION            0
              6 RAISE_VARARGS            1
              8 POP_BLOCK
             10 JUMP_FORWARD            32 (to 44)

  4     >>   12 DUP_TOP
             14 LOAD_GLOBAL              0 (IndexError)
             16 JUMP_IF_TRUE_OR_POP     20
             18 LOAD_GLOBAL              1 (KeyError)
        >>   20 COMPARE_OP              10 (exception match)
             22 POP_JUMP_IF_FALSE       42
             24 POP_TOP
             26 POP_TOP
             28 POP_TOP

  5          30 LOAD_GLOBAL              2 (print)
             32 LOAD_CONST               1 ('Got ya!')
             34 CALL_FUNCTION            1
             36 POP_TOP
             38 POP_EXCEPT
             40 JUMP_FORWARD             2 (to 44)
        >>   42 END_FINALLY
        >>   44 LOAD_CONST               0 (None)
             46 RETURN_VALUE

সুতরাং আমরা দেখতে পাচ্ছি, নির্দেশ 14 প্রথম ক্লাসটিকে IndexErrorস্ট্যাকের উপর চাপিয়ে দেয় । তারপরে এটি পরীক্ষা করে যে সেই মানটি কিনা Trueএটি পাইথনের সত্যতার কারণে এবং অবশেষে যেখানে সরাসরি exception matchসম্পন্ন হয় সেখানে নির্দেশের দিকে ঝাঁপিয়ে পড়ে 20 যেহেতু 18 টি নির্দেশনা এড়িয়ে গেছে, KeyErrorকখনও স্ট্যাকের উপর চাপানো হয়নি এবং সে কারণে এটি মেলে না।

আমি পাইথন ২.7 এবং ৩.6 একই ফলাফল দিয়ে চেষ্টা করেছি।

তবে, কেন এটি বৈধ সিনট্যাক্স? আমি এটি নিম্নলিখিতগুলির মধ্যে একটি বলে ধারণা করছি:

  1. এটি পাইথনের সত্যই পুরানো সংস্করণ থেকে প্রাপ্ত একটি নিদর্শন।
  2. orএকটি exceptধারা মধ্যে ব্যবহার করার জন্য একটি বৈধ ব্যবহারের কেস আছে ।
  3. এটি কেবল পাইথন পার্সারের একটি সীমাবদ্ধতা যা exceptকীওয়ার্ডের পরে কোনও অভিব্যক্তি গ্রহণ করতে পারে ।

আমার ভোট 3 এ আছে (প্রদত্ত আমি পাইথনের নতুন পার্সার সম্পর্কে কিছু আলোচনা দেখেছি) তবে আমি আশা করছি যে কেউ এই অনুমানটি নিশ্চিত করতে পারে। কারণ এটি উদাহরণস্বরূপ 2 হলে, আমি সেই ব্যবহারের ক্ষেত্রেটি জানতে চাই!

এছাড়াও, আমি কীভাবে এই অন্বেষণ চালিয়ে যেতে পারি সে সম্পর্কে আমি কিছুটা নিখুঁত। আমি ভাবছি আমাকে সিপিথন পার্সারের উত্স কোডটি খনন করতে হবে তবে আইডিকে কোথায় এটি পাওয়া যাবে এবং সম্ভবত এর থেকে সহজ উপায় আছে?

উত্তর:


7

ইন except e, eকোনও বৈধ পাইথন এক্সপ্রেশন হতে পারে:

try1_stmt ::=  "try" ":" suite
               ("except" [expression ["as" identifier]] ":" suite)+
               ...

[..] exceptএকটি অভিব্যক্তি সহ একটি ধারাটির জন্য , সেই অভিব্যক্তিটি মূল্যায়ন করা হয়, এবং ফলাফলটি যদি ব্যতিক্রমটির সাথে "সামঞ্জস্যপূর্ণ" হয় তবে এই ধারাটি ব্যতিক্রমের সাথে মিলে যায়। কোনও বস্তু ব্যতিক্রমের সাথে সামঞ্জস্যপূর্ণ যদি তা ব্যতিক্রম বা শ্রেণীর ব্যতিক্রম বিষয়গুলির একটি শ্রেণিকেন্দ্র বা ব্যতিক্রমের সাথে সামঞ্জস্যপূর্ণ আইটেমযুক্ত একটি টুপল।

https://docs.python.org/3/reference/compound_stmts.html#the-try-statement

অভিব্যক্তিটি IndexError or KeyErrorমান দেয় IndexError। সুতরাং এটি সমান:

except IndexError:
   ...

দ্রুত আলো উত্তর দেওয়ার জন্য আপনাকে ধন্যবাদ! আমরা কী এটিকে পার্সারের সীমাবদ্ধতা বিবেচনা করব (অর্থাত্ কেবলমাত্র একটি নির্দিষ্টরূপে যে কোনও অভিব্যক্তি গ্রহণ করতে সক্ষম) বা জিনিসকে খুব বেশি সীমাবদ্ধ না করার জন্য ইচ্ছাকৃত পছন্দ?
Lo Tec Teixeira

1
সরলতর হওয়ার চেয়ে ভাল পাইথন নীতিগুলিকে অবিচল রাখতে আমার কাছে মনে হবে। কেন নতুন নিয়মগুলি সীমাবদ্ধ হতে পারে, যখন কোনও অভিব্যক্তি গ্রহণ করার অর্থ নতুন বিশেষ মামলা ছাড়াই পূর্ণ স্বাধীনতা হয়?
প্রতারণা করুন

এটি একটি ইচ্ছাকৃত পছন্দ, একটিকে ব্যতিক্রমী কয়েকটিকে একত্রিত করার অনুমতি দেয় গতিশীলভাবে ধরতে, এবং একটি exceptবিবৃতিতে এই জাতীয় মান ব্যবহার করে ।
ব্যবহারকারী 4815162342

আমি অনুমান করি যে সম্ভাবনাগুলি সীমাবদ্ধ করার কারণটি হ'ল ডেভেলপারদের কোড লেখা থেকে বিরত রাখা উচিত যা তারা যা ইচ্ছা করেছিল তা করে না। সর্বোপরি, লেখাকে লেখার except IndexError or KeyErrorমতো শালীন জিনিস মনে হয়। তবে আমি আপনাদের সাথে একমত হই যে পাইথন অন্যান্য যে কোনও মূল্যবোধের প্রতি সম্মান দেখানোর চেষ্টা করেছে তার বিরুদ্ধে হবে।
Lo Tec Teixeira

দ্রষ্টব্য যে পাইথন এছাড়াও অনুমতি দেয় var == 1 or 2, যা প্রশিক্ষণহীন চোখকেও "লেখার জন্য একটি শালীন জিনিস বলে মনে হয়"।
এরিক

-2

যৌক্তিক অভিব্যক্তির পরিবর্তে আপনার ধরণের এন-টুপল ব্যবহার করা উচিত (যা কেবল প্রথম অ-মিথ্যা উপাদানটি দেয়):

def with_or_raise(exc):
  try:
    raise exc()
  except (IndexError,KeyError):
    print('Got ya!')

প্রশ্নে বর্ণিত হিসাবে, আমি জানি যে ব্যতিক্রম ক্লাসগুলি একটি টিউপল হিসাবে পাস করা উচিত তবে আমি ভাবছিলাম কেন orএখনও ব্যবহার বৈধ পাইথন ছিল।
Lo Tec Teixeira
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.