বেসএক্সেপশন.ম্যাসেজ পাইথন ২.6 এ অবমুক্ত করা হয়েছে


177

আমি একটি সতর্কতা পেয়েছি যে বেসএক্সেপশন.ম্যাসেজটি পাইথন ২.6 এ অবহিত করা হয়েছে যখন আমি নিম্নলিখিত ব্যবহারকারী-সংজ্ঞায়িত ব্যতিক্রমটি ব্যবহার করি:

class MyException(Exception):

    def __init__(self, message):
        self.message = message

    def __str__(self):
        return repr(self.message)

এই সতর্কতা:

DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
self.message = message

এতে দোষ কী? অবমূল্যায়নের সতর্কতা থেকে মুক্তি পেতে আমার কী পরিবর্তন করতে হবে?


9
পিইপি 352 দেখুন: পাইথন.অর্গ
দেবদেবী

উত্তর:


154

সমাধান - প্রায় কোনও কোডিংয়ের প্রয়োজন নেই

কেবলমাত্র আপনার ব্যতিক্রম শ্রেণীর উত্তরাধিকারী করুন Exceptionএবং কনস্ট্রাক্টরের কাছে প্রথম পরামিতি হিসাবে বার্তাটি দিন

উদাহরণ:

class MyException(Exception):
    """My documentation"""

try:
    raise MyException('my detailed description')
except MyException as my:
    print my # outputs 'my detailed description'

আপনি কাস্টম বার্তা অ্যাক্সেস করতে str(my)বা ব্যবহার করতে পারেন (কম মার্জিত) my.args[0]

পটভূমি

পাইথনের নতুন সংস্করণগুলিতে (২.6 থেকে) বেসে এক্সেপশন থেকে উত্তরাধিকারসূত্রে ( পাইথন ২.২ থেকে শুরু হওয়া ) আমাদের কাস্টম ব্যতিক্রম ক্লাসগুলির উত্তরাধিকারী হওয়ার কথা। ব্যাকগ্রাউন্ডটি PEP 352- তে বিশদভাবে বর্ণিত হয়েছে ।

class BaseException(object):

    """Superclass representing the base of the exception hierarchy.
    Provides an 'args' attribute that contains all arguments passed
    to the constructor.  Suggested practice, though, is that only a
    single string argument be passed to the constructor."""

__str__এবং __repr__ইতিমধ্যে অর্থবহ উপায়ে কার্যকর করা হয়েছে, বিশেষত কেবলমাত্র একটি যুক্তির ক্ষেত্রে (যা বার্তা হিসাবে ব্যবহার করা যেতে পারে)।

অন্যের পরামর্শ অনুসারে আপনার পুনরাবৃত্তি __str__বা __init__বাস্তবায়ন বা তৈরি করার দরকার নেই _get_message


5
@ ম্যাট
গিকিকিউ

8
strবিরতি ব্যবহার করা যদি ব্যতিক্রমটি ইউনিকোড যুক্তি দিয়ে তৈরি করা হয়েছিল: str(MyException(u'\xe5'))উত্থাপন করে UnicodeEncodeError। এর unicodeপরিবর্তে ব্যবহার করা strবুদ্ধিমানের নয় কারণ unicode(MyException('\xe5'))ইউনিকোডডেকোডেরর উত্থাপন করে। এর অর্থ কি এই যে যুক্তিটি যদি আমি আগেই না জানতাম strবা unicode, .args[0]আমি আগে যেখানে ব্যবহার করেছি সেখানে আমাকে ব্যবহার করতে হবে .message?
ক্যাস্পার্ড

1
@ ক্যাস্পারড ভার্চুয়ালি সমস্ত পাইথন ইউনিকোড ইস্যুগুলির মতো এটিও ইউনিকোড স্যান্ডউইচ দিয়ে সমাধান করা যেতে পারে ।
রায়ান পি

3
@ আরআইএনপি এটি ধরে নিয়েছে যে যা হয় তাতে আমার আসলেই নিয়ন্ত্রণ থাকে Here এখানে আমি জীবনের একটি বাস্তব ঘটনাটি দেখলাম। আমাকে একাধিক তৃতীয় পক্ষের লাইব্রেরি থেকে ব্যতিক্রমগুলি পরিচালনা করতে হবে। তাদের কিছু ব্যতিক্রম ইউনিকোড এবং কিছু পাস স্ট্রিম। একটি লাইব্রেরির এমনকি নিজস্ব শ্রেণি রয়েছে যা ইউনিকোড থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয় তবে তার নিজস্ব পুনরায় পদ্ধতি রয়েছে যা অনুকরণের পরিবর্তে ইউনিকোডের পরিবর্তে ইউনিকোড দেয়।
ক্যাস্পারড

1
আমি বিটিডব্লু করেছি। .messageআমাদের প্রকল্পের সমস্ত ব্যবহারের সাথে প্রতিস্থাপন করুন .args[0]এবং এটি আমাদের জন্য কোনও সমস্যা তৈরি করে না।
ক্যাস্পারড

26

হ্যাঁ, এটি পাইথন ২.6 এ হ্রাস পেয়েছে কারণ এটি পাইথন ৩.০ এ চলে যাচ্ছে

বেসএক্সেপশন ক্লাস ত্রুটি বার্তা সংরক্ষণের কোনও উপায় সরবরাহ করে না। আপনাকে এটি নিজে প্রয়োগ করতে হবে। আপনি একটি সাবক্লাসের সাহায্যে এটি করতে পারেন যা বার্তাটি সংরক্ষণের জন্য কোনও সম্পত্তি ব্যবহার করে।

class MyException(Exception):
    def _get_message(self): 
        return self._message
    def _set_message(self, message): 
        self._message = message
    message = property(_get_message, _set_message)

আশাকরি এটা সাহায্য করবে


1
উত্থাপনের সময় আপনি কীভাবে বার্তাটি শুরু করবেন? তার কোডটি মাইএক্সেপশন ("কিছু বার্তা") কল করে বার্তাটি সেট করা হচ্ছে তা দেখিয়েছিল
eric.frederich

আমার উদাহরণের পদ্ধতিগুলি কেবল বার্তার সম্পত্তি বাস্তবায়নের জন্য। সম্পত্তি কীভাবে ব্যবহৃত হয় তা কোডার পর্যন্ত। এই ক্ষেত্রে ওপি তার কোডটিতে পোস্ট করা আরম্ভ এবং স্ট্রিং পদ্ধতিগুলি ব্যবহার করে ।
সহস

1
গেটর / সেটারের পরিবর্তে সর্বজনীন ভেরিয়েবল ব্যবহার করার বিষয়টি বিবেচনা করুন, যদি এটি কেবল অন্য ভেরিয়েবলটি পড়ে reads আপনি @propertyযখন সত্যই এনক্যাপসুলেশন প্রয়োজন তখন আপনি পরে সর্বদা একটি সিনট্যাক্সে আপগ্রেড করতে পারেন ।
vdboor

2
@vdboor: তিনি হ্রাসের @propertyসতর্কতাটি অক্ষম করতে ব্যবহার করছেন ।
বুকজর

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

9
class MyException(Exception):

    def __str__(self):
        return repr(self.args[0])

e = MyException('asdf')
print e

এটি পাইথন 2.6 স্টাইলে আপনার ক্লাস। নতুন ব্যতিক্রমটি একটি স্বেচ্ছাসেবী যুক্তিতে লাগে takes


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

8

কিভাবে সতর্কতা প্রতিলিপি

আমি সমস্যাটি স্পষ্ট করে বলি, যেহেতু কেউ প্রশ্নের নমুনা কোডটির সাথে এটির অনুলিপি করতে পারে না, এটি পাইথন ২.6 এবং ২.7 এ সতর্কতাটির প্রতিলিপি তৈরি করবে, যদি আপনি সতর্কতা চালু করেন ( -Wপতাকা , PYTHONWARNINGSপরিবেশ পরিবর্তনশীল, বা সতর্কতা মডিউল ):

>>> error = Exception('foobarbaz')
>>> error.message
__main__:1: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
'foobarbaz'

ব্যবহার বন্ধ করুন .message

আমি পছন্দ করি repr(error), যা ত্রুটির প্রকারের নাম, বার্তাটির পুনরায়, যদি সেখানে থাকে এবং অবশিষ্ট আর্গুমেন্টগুলির repr থাকে এমন একটি স্ট্রিং প্রত্যাবর্তন করে।

>>> repr(error)
"Exception('foobarbaz',)"

সতর্কতা অবলম্বন করার পরেও ব্যবহার করা হচ্ছে .message

এবং যেভাবে আপনি পরিত্রাণ পাবেন তা DeprecationWarningহ'ল পাইথন ডিজাইনাররা যেমনটি লিখেছিলেন তেমন একটি বিল্টিন ব্যতিক্রম সাবক্লাস করা:

class MyException(Exception):

    def __init__(self, message, *args):
        self.message = message
        # delegate the rest of initialization to parent
        super(MyException, self).__init__(message, *args)

>>> myexception = MyException('my message')
>>> myexception.message
'my message'
>>> str(myexception)
'my message'
>>> repr(myexception)
"MyException('my message',)"

.messageছাড়া শুধু গুণাবলী পেয়েerror.message

যদি আপনি জানেন যে ব্যতিক্রমটির জন্য একটি যুক্তি, একটি বার্তা ছিল এবং এটি আপনি চান তবে বার্তাটির বৈশিষ্ট্যটি এড়ানো এবং কেবল strত্রুটিটি গ্রহণ করা ভাল। সাবক্ল্যাসডের জন্য বলুন Exception:

class MyException(Exception):
    '''demo straight subclass'''

এবং ব্যবহার:

>>> myexception = MyException('my message')
>>> str(myexception)
'my message'

এই উত্তরটি দেখুন:

আধুনিক পাইথনে কাস্টম ব্যতিক্রম ঘোষণা করার সঠিক উপায়?


4

আমি যতদূর বলতে পারি, বার্তা বিশিষ্টটির জন্য কেবল আলাদা নাম ব্যবহার করা বেস শ্রেণীর সাথে বিরোধ এড়ানো যায় এবং এইভাবে অবমূল্যায়ন সতর্কতা বন্ধ করে দেয়:

class MyException(Exception):

def __init__(self, message):
    self.msg = message

def __str__(self):
    return repr(self.msg)

আমার কাছে হ্যাক লাগছে।

সাব-ক্লাস একটি বার্তাের বৈশিষ্ট্য স্পষ্টভাবে সংজ্ঞায়িত করেও কেউ সতর্কতা জারি করার কারণ ব্যাখ্যা করতে পারে। যদি বেস শ্রেণীর আর এই বৈশিষ্ট্য না থাকে তবে কোনও সমস্যা হওয়া উচিত নয়।


4

গিকিকিউ এর উত্তর থেকে চালিয়ে যাওয়া , পছন্দের কোড প্রতিস্থাপন আপনার যা করা দরকার তার উপর নির্ভর করে:

### Problem
class MyException(Exception):
    """My documentation"""

try:
    raise MyException('my detailed description')
except MyException as my:
    ### Solution 1, fails in Python 2.x if MyException contains 🔥
    # with UnicodeEncodeError: 'ascii' codec can't encode characters in position 24-25: ordinal not in range(128)
    print(my)  # outputs 'my detailed description'

### Solution 2
# Works in Python 2.x if exception only has ASCII characters,
# should always work in Python 3.x
str(my)

### Solution 3
# Required in Python 2.x if you need to handle non-ASCII characters,
# such as δσφφδσ (as pointed out by jjc) or emoji 🔥 💕 🎁 💯 🌹
# but does not work in Python 3.x
unicode(my)

কখনও কখনও ব্যতিক্রম একাধিক যুক্তি আছে, তাই my.args[0] সমস্ত প্রাসঙ্গিক তথ্য সরবরাহ করার নিশ্চয়তা দেওয়া হয় না।

এই ক্ষেত্রে:

# Python 2.7
try:
    u'\u12345'.encode('utf-8').encode('utf-8')
except UnicodeDecodeError as e:
    print e.args[0]
    print e.args
    print str(e)

আউটপুট হিসাবে মুদ্রণ:

ascii
('ascii', '\xe1\x88\xb45', 0, 1, 'ordinal not in range(128)')
'ascii' codec can't decode byte 0xe1 in position 0: ordinal not in range(128)

তবে এটি একটি প্রসঙ্গে সংবেদনশীল বাণিজ্য বন্ধ, কারণ উদাহরণস্বরূপ:

# Python 2.7
>>> str(SyntaxError())
'None'
# 'None' compares True which might not be expected

1
হ্যাঁ, এটি overthink করবেন না। str(my)পরিবর্তে ব্যবহার করুন my.message
ক্রিশ্চিয়ান লং

1

আরআর (আমার ধারণা) ব্যবহারের পরামর্শটি পাইথন ২.7-এ ইউনিকোড সমস্যার দিকে নিয়ে যায়, যেমন:

str(Exception(u'δσφφδσ'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: ordinal not in range(128)

:(

unicode(Exception(u'δσφφδσ')) 

প্রত্যাশিত হিসাবে কাজ করে এবং ত্রুটি স্ট্রিংয়ের কিছু বিষয়বস্তুতে ব্যবহারকারী ইনপুট অন্তর্ভুক্ত থাকে এমন ক্ষেত্রে অগ্রাধিকার দেওয়া হয়


1

pzrq এর পোস্ট ব্যবহার করতে বলেছেন:

str(e)

এটি আমার প্রয়োজন ঠিক ছিল।

(আপনি যদি একটি ইউনিকোড পরিবেশে থাকেন তবে এটি প্রদর্শিত হয়:

unicode(e)

কাজ করবে, এবং এটি অ-ইউনিকোড পরিবেশে দুর্দান্ত কাজ করবে বলে মনে হচ্ছে)

Pzrq অন্যান্য অনেক ভাল জিনিস বলেছিলেন, তবে সমস্ত ভাল স্টাফের কারণে আমি তাদের উত্তর প্রায় মিস করেছি। যেহেতু আমার ৫০ টি পয়েন্ট নেই, আমি কার্যকর উত্তরটির দিকে মনোযোগ আকর্ষণ করার প্রয়াসে তাদের উত্তর সম্পর্কে মন্তব্য করতে পারি না এবং যেহেতু আমার 15 টি নেই আমি উত্তরটি ভোট দিতে পারি না, তবে আমি পোস্ট করতে পারি (পিছিয়ে পড়া অনুভব করি তবে ওহ ভাল) - সুতরাং এখানে আমি পোস্ট করছি - সম্ভবত এর জন্য পয়েন্ট হারাতে হবে ...

যেহেতু আমার বক্তব্যটি pzrq এর উত্তরের দিকে দৃষ্টি আকর্ষণ করা, তাই দয়া করে ঝলকানি না এবং নীচের সমস্তটিতে এটি মিস করবেন না। এই পোস্টের প্রথম কয়েকটি লাইন সর্বাধিক গুরুত্বপূর্ণ।

আমার গল্প:

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

আমি ব্যবহার করছিলাম:

except Exception as e:
   print '%s (%s)' % (e.message,type(e))

যা আমরা এখন সবাই জানি, ওপি সম্পর্কে জিজ্ঞাসা করা সতর্কবার্তা দেয় (যা আমাকে এখানে এনেছে), এবং এটি, যা কাজটি করার উপায় হিসাবে pzrq দেয়:

except Exception as e:
   print '%s (%s)' % (str(e),type(e))

না।

আমি কোনও ইউনিকোড পরিবেশে নেই, তবে জেজেসি-র উত্তর আমাকে অবাক করে দিয়েছে, তাই আমাকে এটি চেষ্টা করে দেখতে হয়েছিল। এই প্রসঙ্গে এটি হয়ে যায়:

except Exception as e:
   print '%s (%s)' % (unicode(e),type(e))

যা আমার অবাক করে দিয়েছিল ঠিক (ঙ) এর মতো - তাই এখন আমি ব্যবহার করছি।

জানেন না যে 'স্ট্রিং (ই) / ইউনিকোড (ই)' অনুমোদিত পাইথন পথ ', এবং আমি সম্ভবত 3.0 এ পৌঁছানোর পরে কেন এটি ভাল নয় তা খুঁজে পেতে পারি, তবে একজন আশা করে যে একটি হ্যান্ডেল করার ক্ষমতা অপ্রত্যাশিত ব্যতিক্রম (*) মারা না গিয়ে এবং এখনও সেখান থেকে কিছু তথ্য পাবেন না ...

(*) হুম। "অপ্রত্যাশিত ব্যতিক্রম" - আমি মনে করি আমি কেবল তোতলা!

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