পাইথন: একক লাইনে স্টেট স্টেটমেন্ট


97

একক লাইনে বাদ দিয়ে অজগরকে কী চেষ্টা করে দেখার উপায় আছে?

কিছুটা এইরকম...

b = 'some variable'
a = c | b #try statement goes here

কোথায় bঘোষিত ভেরিয়েবল এবং cতা নয় ... সুতরাং cএকটি ত্রুটি ফেলে aদেবে এবং হয়ে যাবে b...

উত্তর:


63

পাইথনের একক লাইনে একটি try/ exceptব্লক সংকোচনের কোনও উপায় নেই ।

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


আপনি যদি না সকল নামের আপনাকে প্রথমে আগ্রহী দায়িত্ব অর্পণ করা, আপনি বিকল্প ব্যবহার করতে পারেন না।

  • সেরা বিকল্প একটি বিবৃতি হয়।

    c = None
    b = [1, 2]
    
    if c is None:
        a = b
    else:
        a = c
    
  • ওয়ান-লাইনার বিকল্পটি শর্তাধীন অভিব্যক্তি।

    c = None
    b = [1, 2]
    a = c if c is not None else b
    
  • কিছু লোক এটি করার জন্য শর্ট সার্কিট আচরণকে অপব্যবহার করে orএটি ত্রুটিযুক্ত প্রবণ, তাই আমি কখনই এটি ব্যবহার করি না।

    c = None
    b = [1, 2]
    a = c or b
    

    নিম্নলিখিত বিষয় বিবেচনা করুন:

    c = []
    b = [1, 2]
    a = c or b
    

    এই ক্ষেত্রে, aসম্ভবত হওয়া উচিত [], তবে এটি [1, 2]কারণ []এটি বুলিয়ান প্রসঙ্গে মিথ্যা। কারণ প্রচুর মান রয়েছে যা মিথ্যা হতে পারে, আমি orকৌশলটি ব্যবহার করি না । (লোকে if foo:যখন বোঝাতে চাইবে তখন লোকেদের একই সমস্যা দেখা দেয় if foo is not None:))


ধন্যবাদ সমস্যাটি হ'ল এটি আসলে একটি জাঙ্গো মডেল ob কোনও ডেটা না পাওয়া গেলে .get ত্রুটি প্রদান করে ... এটি কিছুই ফেরায় না (যা আমাকে বিরক্ত করে)
ব্র্যান্ট

@ ব্র্যান্ট, ঠিক আছে, কোনও ভেরিয়েবল সেট করা আছে কিনা তা পরীক্ষা করার চেয়ে পরিস্থিতি কিছুটা আলাদা (পাইথনে কোনও ভেরিয়েবল ঘোষিত হয় না)। পাইথনের সাধারণ স্টাইলটি হ'ল মান হিসাবে ত্রুটিগুলি ফিরিয়ে নেওয়া ব্যতিক্রম বাড়াতে পছন্দ করে, যা আমাদের মধ্যে অনেকে আসলে পছন্দ করে। প্রতিবার কোনও অপারেশনের রিটার্ন কোড পরীক্ষা করে নেওয়া এবং ত্রুটিগুলি সন্ধান করার জন্য যদি খুব কষ্ট হয় তবে আমি পাইথন লেখার সময় সি সম্পর্কে অবশ্যই মিস করব না। যে কোনও ইভেন্টে, যদিও এটি নিয়ে আলোচনা হয়েছে, তবে try/ exceptব্লকের জন্য কোনও এক-লাইন সিনট্যাক্স নেই । ভাগ্যক্রমে লাইনগুলি সস্তা, সুতরাং 4-লাইনের সমাধানটি আপনার পক্ষে কাজ করা উচিত। ;-)
মাইক গ্রাহাম

এটি ডিকের অভ্যন্তরে বড় আকারের টিপলগুলির অংশ ... আমি কেবল কিছুটা ছোট করার চেষ্টা করছিলাম
ব্র্যান্ট

4
getআপনি ব্যতিক্রম না চাইলে ব্যবহার করবেন না । filterপরিবর্তে ব্যবহার করুন।
jcdyer

@ মাইক্রগ্রাহ ভাল উত্তর - একটি সংকেত (লিঙ্ক?) কেন সংক্ষিপ্ত-সার্কিট করা ত্রুটিযুক্ত প্রবণতাটি দুর্দান্ত হবে।
kratenko

85

এটি মারাত্মকভাবে হ্যাকিশ, তবে আমি যখন এটি ডিবাগিংয়ের জন্য ক্রমগুলির ক্রম লিখতে চেয়েছিলাম তখনই আমি এটি প্রম্পটে ব্যবহার করেছি:

exec "try: some_problematic_thing()\nexcept: problem=sys.exc_info()"
print "The problem is %s" % problem[1]

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

আপনি যে বাস্তব উদ্দেশ্যটি সম্পাদন করতে চেষ্টা করছেন তার জন্য, আপনি চেষ্টা করতে পারেন locals().get('c', b); আদর্শগতভাবে স্থানীয় প্রসঙ্গে পরিবর্তে একটি আসল অভিধান ব্যবহার করা ভাল, বা যা-না-সেট সেট না করে চালানোর আগে কেবল কোনওটিকেই সি প্রদান করুন।


26
আরে, এই প্রশ্নের উত্তর! :)
স্টিভ বেনেট

4
এই উত্তরটি, সুপার অগোছালো, তবে এক লাইনে পছন্দ করুন, ঠিক আমার পছন্দ মতো।
প্যাট্রিক কুক

এই উত্তর !! হবে problem[0]কি যে ফাংশন আয় ফিরে আসতে?
এসআইসলাম

4
এক্সেক একটি কোড গন্ধ এবং অন্য কিছু কাজ না করে এড়ানো উচিত। যদি একটি লাইন কোড এত গুরুত্বপূর্ণ হয় তবে এটি কাজ করবে, তবে আপনাকে নিজেরাই জিজ্ঞাসা করতে হবে কেন একটি লাইন এত গুরুত্বপূর্ণ।
গেউথিন

4
পরিষ্কারভাবে উত্পাদন ব্যবহারের জন্য নয়, তবে একটি বিশ্রী ডিবাগিং সেশনের জন্য ঠিক কী প্রয়োজন।
থারস্মমনার


13

অন্য উপায়টি একটি প্রসঙ্গ পরিচালককে সংজ্ঞায়িত করা হয়:

class trialContextManager:
    def __enter__(self): pass
    def __exit__(self, *args): return True
trial = trialContextManager()

তারপরে withএকটি একক লাইনে ত্রুটি উপেক্ষা করতে বিবৃতিটি ব্যবহার করুন :

>>> with trial: a = 5      # will be executed normally
>>> with trial: a = 1 / 0  # will be not executed and no exception is raised
>>> print a
5

রানটাইম ত্রুটির ক্ষেত্রে কোনও ব্যতিক্রম উত্থাপিত হবে না। এটি একটি try:ছাড়া একটি মত except:


4
এটা অসাধারণ! যেহেতু কোনও স্পষ্ট চেষ্টা / বাদে নেই, আপনি কীভাবে প্রসঙ্গ পরিচালকটি ত্রুটিগুলি মোকাবেলা করতে পারেন তা সংক্ষেপে ব্যাখ্যা করতে পারবেন?
প্যাট্রিক

10

সীমিত প্রত্যাশিত ব্যতিক্রম সহ poke53280 উত্তরের সংস্করণ।

def try_or(func, default=None, expected_exc=(Exception,)):
    try:
        return func()
    except expected_exc:
        return default

এবং এটি হিসাবে ব্যবহার করা যেতে পারে

In [2]: try_or(lambda: 1/2, default=float('nan'))
Out[2]: 0.5

In [3]: try_or(lambda: 1/0, default=float('nan'), expected_exc=(ArithmeticError,))
Out[3]: nan

In [4]: try_or(lambda: "1"/0, default=float('nan'), expected_exc=(ArithmeticError,))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
[your traceback here]
TypeError: unsupported operand type(s) for /: 'str' and 'int'

In [5]: try_or(lambda: "1"/0, default=float('nan'), expected_exc=(ArithmeticError, TypeError))
Out[5]: nan

"প্রত্যাশিত_এক্সসি = (ব্যতিক্রম,)" এর জন্য কমাটি কী? আপনি দয়া করে ব্যাখ্যা করতে পারেন?
ইবিলজেন

4
একটি থেকে অভিব্যক্তি @ibilgen কমা ধর্মান্তরিত tuple । লেখার (Exception)বন্ধনী ছেড়ে দেওয়ার সমান। (Exception, )দোভাষীকে বলে যে এটি একটি প্রবেশিকা সহ একটি টিপল (তালিকার মতো কিছু)। এই উদাহরণে এটি ব্যবহৃত হয় তাই expected_excএকাধিক ব্যতিক্রম হতে পারে।
miile7


5

সমস্যাটি হ'ল এটি আসলে একটি জ্যাঙ্গো মডেল.অবজেক্টস.জেট ক্যোয়ারী যা আমি পরীক্ষার চেষ্টা করছি। কোনও ডেটা না পাওয়া গেলে .get ত্রুটি প্রদান করে ... এটি কিছুই ফেরায় না (যা আমাকে বিরক্ত করে)

এর মতো কিছু ব্যবহার করুন:

print("result:", try_or(lambda: model.objects.get(), '<n/a>'))

যেখানে ট্রাই_অর আপনার দ্বারা নির্ধারিত একটি ইউটিলিটি ফাংশন:

def try_or(fn, default):
    try:
        return fn()
    except:
        return default

বৈকল্পিকভাবে আপনাকে গৃহীত ব্যতিক্রম ধরনের সীমিত করতে পারে NameError, AttributeErrorইত্যাদি


5

কিভাবে দুটি লাইন ব্যবহার সম্পর্কে। ঠিক আছে ?

>>> try: a = 3; b= 0; c = a / b
... except : print('not possible'); print('zero division error')
...
not possible
zero division error

4

ব্যবহার করে আপনি নামস্থান অভি অ্যাক্সেস করার মাধ্যমে এটা করতে পারেন vars(), locals()অথবা globals()যেটা আপনার অবস্থা সবচেয়ে উপযুক্ত।

>>> b = 'some variable'
>>> a = vars().get('c', b)

4
এটি ভেরিয়েবল সেট করা আছে কিনা তা যাচাই করার মতো ঠিক একই রকম কাজ করে না (যদিও আপনি যদি কোনও নির্দিষ্ট সুযোগে আগ্রহী হন তবে এটি তা করে।) এছাড়াও, www.wwwwwwww .....
মাইক গ্রাহাম

2

আপনি উল্লেখ করেছেন যে আপনি জ্যাঙ্গো ব্যবহার করছেন। আপনি যদি যা করছেন তা যদি তা বোঝায় তবে আপনি ব্যবহার করতে পারেন:

my_instance, created = MyModel.objects.get_or_create()

createdসত্য বা মিথ্যা হবে। হয়তো এই আপনাকে সাহায্য করবে।


2

ওয়াল্টার মুন্ড দ্বারা অনুপ্রাণিত পাইথন 3 এ কাজ করে

exec("try:some_problematic_thing()\nexcept:pass")

মাল্টিপ্লেস লাইনের জন্য এক লাইনে

exec("try:\n\tprint('FirstLineOk')\n\tsome_problematic_thing()\n\tprint('ThirdLineNotTriggerd')\nexcept:pass")

পিএস: এক্সিকিউট আপনার নিয়ন্ত্রণে নেই এমন ডেটা ব্যবহার করা নিরাপদ।


1

যদি আপনাকে আসলে ব্যতিক্রমগুলি পরিচালনা করতে হয়:
(poke53280 এর উত্তর থেকে সংশোধিত)

>>> def try_or(fn, exceptions: dict = {}):
    try:
        return fn()
    except Exception as ei:
        for e in ei.__class__.__mro__[:-1]:
            if e in exceptions: return exceptions[e]()
        else:
            raise


>>> def context():
    return 1 + None

>>> try_or( context, {TypeError: lambda: print('TypeError exception')} )
TypeError exception
>>> 

মনে রাখবেন যে ব্যতিক্রমটি সমর্থন না করা থাকলে এটি প্রত্যাশার মতো বাড়িয়ে তুলবে:

>>> try_or( context, {ValueError: lambda: print('ValueError exception')} )
Traceback (most recent call last):
  File "<pyshell#57>", line 1, in <module>
    try_or( context, {ValueError: lambda: print('ValueError exception')} )
  File "<pyshell#38>", line 3, in try_or
    return fn()
  File "<pyshell#56>", line 2, in context
    return 1 + None
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
>>> 

এছাড়াও যদি Exceptionদেওয়া হয় তবে এটি নীচের কিছুতেই মিলবে।
( BaseExceptionউচ্চতর, সুতরাং এটি মেলে না)

>>> try_or( context, {Exception: lambda: print('exception')} )
exception


0

withএক লাইনে বাক্য গঠন ব্যবহার করুন :

class OK(): __init__ = lambda self, *isok: setattr(self, 'isok', isok); __enter__ = lambda self: None; __exit__ = lambda self, exc_type, exc_value, traceback: (True if not self.isok or issubclass(exc_type, self.isok) else None) if exc_type else None

কোনও ত্রুটি উপেক্ষা করুন:

with OK(): 1/0

নির্দিষ্ট ত্রুটি উপেক্ষা করুন:

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