python - সহজ ভাষায় পাইথন ৩ pdf download




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

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

এটি ঠিক আছে, যদি না আপনার ব্যতিক্রম সত্যিই একটি নির্দিষ্ট ব্যতিক্রমের একটি টাইপ হয়:

class MyException(Exception):
    pass

অথবা ভাল (সম্ভবত নিখুঁত), পরিবর্তে একটি ডকস্ট্রিং দিতে pass :

class MyException(Exception):
    """Raise for my specific kind of exception"""

Subclassing ব্যতিক্রম subclasses

docs থেকে

Exception

সমস্ত অন্তর্নির্মিত, অ-সিস্টেম-বহির্গামী ব্যতিক্রম এই বর্গ থেকে উদ্ভূত হয়। সমস্ত ব্যবহারকারী-সংজ্ঞায়িত ব্যতিক্রম এই বর্গ থেকে প্রাপ্ত করা উচিত।

এর মানে হল যে যদি আপনার ব্যতিক্রমটি একটি নির্দিষ্ট ব্যতিক্রমের একটি প্রকারের হয় তবে উপশ্রেণীটি জেনারিক ব্যতিক্রমের পরিবর্তে Exception (এবং ফলাফলটি যে আপনি এখনও Exception হিসাবে ডক্সগুলির সুপারিশ হিসাবে প্রাপ্ত হন)। এছাড়াও, আপনি অন্তত একটি ডকস্ট্রিং সরবরাহ করতে পারেন (এবং pass কীওয়ার্ড ব্যবহার করতে বাধ্য করা হবে না):

class MyAppValueError(ValueError):
    '''Raise when my specific value is wrong'''

আপনি একটি কাস্টম __init__ সঙ্গে নিজেকে তৈরি বৈশিষ্ট্যাবলী সেট করুন। একটি অবস্থানগত যুক্তি হিসাবে একটি স্বর পাস এড়িয়ে চলুন, আপনার কোড ভবিষ্যতে ব্যবহারকারীদের আপনাকে ধন্যবাদ হবে। আপনি অপ্রচলিত বার্তা বৈশিষ্ট্যটি ব্যবহার করলে, এটি নিজেকে নির্দিষ্ট করে একটি DeprecationWarning এড়ানো হবে:

class MyAppValueError(ValueError):
    '''Raise when a specific subset of values in context of app is wrong'''
    def __init__(self, message, foo, *args):
        self.message = message # without this you may get DeprecationWarning
        # Special attribute you desire with your Error, 
        # perhaps the value that caused the error?:
        self.foo = foo         
        # allow users initialize misc. arguments as any other builtin Error
        super(MyAppValueError, self).__init__(message, foo, *args) 

আপনার নিজস্ব __str__ বা __repr__ লিখতে সত্যিই কোন প্রয়োজন নেই। বিল্টিনগুলি খুব সুন্দর, এবং আপনার সহযোগী উত্তরাধিকার নিশ্চিত করে যে আপনি এটি ব্যবহার করেন।

শীর্ষ উত্তর Critique

হয়তো আমি প্রশ্ন মিস করেছি, কিন্তু কেন না:

class MyException(Exception):
    pass

আবার, উপরে থাকা সমস্যাটি এটি ধরার জন্য, আপনাকে এটি বিশেষভাবে নামকরণ করতে হবে (অন্যত্র তৈরি হলে এটি আমদানি করুন) অথবা ব্যতিক্রমটি ধরুন, তবে আপনি সম্ভবত সমস্ত ধরণের ব্যতিক্রমগুলি পরিচালনা করার জন্য প্রস্তুত নন, এবং আপনি শুধুমাত্র হ্যান্ডেল করতে প্রস্তুত ব্যতিক্রম ধরতে হবে)। নিচের মত সমালোচনা, কিন্তু উপরন্তু এটি সুপারের মাধ্যমে সূচনা করার উপায় নয়, এবং যদি আপনি বার্তা বৈশিষ্ট্যটি অ্যাক্সেস করেন তবে আপনি একটি DeprecationWarning পাবেন:

সম্পাদনা করুন: কিছু ওভাররাইড (অথবা অতিরিক্ত আর্গুমেন্ট পাস), এটি করুন:

class ValidationError(Exception):
    def __init__(self, message, errors):

        # Call the base class constructor with the parameters it needs
        super(ValidationError, self).__init__(message)

        # Now for your custom code...
        self.errors = errors

এভাবে আপনি দ্বিতীয় প্যারামিটারে ত্রুটির বার্তাগুলি সংকেত প্রেরণ করতে পারেন এবং পরে এটি e.errors দিয়ে পেতে পারেন

এটিও ঠিক দুইটি আর্গুমেন্ট দরকার ( self থেকে।) আর নেই, কম নয়। যে একটি ভবিষ্যত ব্যবহারকারীদের প্রশংসা করতে পারে না যে একটি আকর্ষণীয় সীমাবদ্ধতা।

সরাসরি হতে - এটি Liskov substitutability লঙ্ঘন করে।

আমি উভয় ত্রুটি প্রদর্শন করবো:

>>> ValidationError('foo', 'bar', 'baz').message

Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    ValidationError('foo', 'bar', 'baz').message
TypeError: __init__() takes exactly 3 arguments (4 given)

>>> ValidationError('foo', 'bar').message
__main__:1: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
'foo'

তুলনা করা:

>>> MyAppValueError('foo', 'FOO', 'bar').message
'foo'

আধুনিক Python মধ্যে কাস্টম ব্যতিক্রম ক্লাস ঘোষণা করার সঠিক উপায় কি? আমার প্রাথমিক লক্ষ্যটি যে কোনও ব্যতিক্রমমূলক ব্যতিক্রম ব্যতিক্রমগুলি অনুসরণ করতে হয়, যাতে (ব্যতিক্রম হিসাবে) যে কোনও অতিরিক্ত স্ট্রিং আমি ব্যতিক্রমতে অন্তর্ভুক্ত করি তা ব্যতিক্রম দ্বারা ধরা পড়ে।

"আধুনিক পাইথন" এর দ্বারা আমি পাইথন 2.5 তে চালিত কিছু বলতে চাই তবে পাইথন 2.6 এবং পাইথন 3 * এর জন্য 'সঠিক' হতে হবে। এবং "কাস্টম" দ্বারা আমার একটি ব্যতিক্রম বস্তু রয়েছে যা ত্রুটিটির কারণ সম্পর্কে অতিরিক্ত তথ্য অন্তর্ভুক্ত করতে পারে: একটি স্ট্রিং, সম্ভবত ব্যতিক্রমটির সাথে সম্পর্কিত অন্য কিছু ইচ্ছাকৃত বস্তুও হতে পারে।

Python 2.6.2-এ নিম্নলিখিত অব্যবহার্য সতর্কবার্তা দ্বারা আমাকে টপ করা হয়েছিল:

>>> class MyError(Exception):
...     def __init__(self, message):
...         self.message = message
... 
>>> MyError("foo")
_sandbox.py:3: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6

এটি উন্মাদ বলে মনে হয় যে BaseException নামের message জন্য বিশেষ অর্থ রয়েছে। আমি PEP-352 থেকে একত্রিত হয়েছি যে এ্যাট্রিবিউটটির বিশেষ অর্থ ছিল 2.5 তারা দূরে চলে যাওয়ার চেষ্টা করছে, তাই আমি অনুমান করছি যে সেই নামটি (এবং সেই একমাত্র) এখন নিষিদ্ধ? বিতৃষ্ণা।

আমি অদ্ভুতভাবে সচেতন যে Exception কিছু ম্যাজিক পরামিতি args , কিন্তু আমি কিভাবে এটি ব্যবহার করতে জানি না। আমি নিশ্চিত নই যে এটা এগিয়ে যাওয়ার জন্য সঠিক উপায়; অনলাইনে পাওয়া বেশিরভাগ আলোচনায় তারা পাইথন 3 এ যুক্তি দিয়ে কাজ করার চেষ্টা করছিল।

আপডেট: দুই উত্তর __init__ , এবং __str__ / __unicode__ / __repr__ ওভাররাইড করার পরামর্শ __repr__ । এটি অনেক টাইপিং এর মতো মনে হচ্ছে, এটা কি প্রয়োজন?


আধুনিক পাইথন ব্যতিক্রমগুলির সাথে, আপনাকে অপব্যবহারের দরকার নেই। .message , বা ওভাররাইড .message .__str__() অথবা .__repr__() অথবা এটির কোনও। আপনার ব্যতিক্রমটি উত্থাপিত হলে আপনি যা চান তা একটি তথ্যপূর্ণ বার্তা, এটি করুন:

class MyException(Exception):
    pass

raise MyException("My hovercraft is full of eels")

এটি MyException: My hovercraft is full of eels সাথে একটি ট্রেসব্যাক শেষ করে MyException: My hovercraft is full of eels

আপনি ব্যতিক্রম থেকে আরো নমনীয়তা চান, আপনি যুক্তি হিসাবে একটি অভিধান পাস করতে পারে:

raise MyException({"message":"My hovercraft is full of animals", "animal":"eels"})

যাইহোক, ব্লক except যে বিবরণ পেতে একটি বিট আরো জটিল। বিবরণ args বৈশিষ্ট্য সংরক্ষিত হয়, যা একটি তালিকা। আপনি এই মত কিছু করতে হবে:

try:
    raise MyException({"message":"My hovercraft is full of animals", "animal":"eels"})
except MyException as e:
    details = e.args[0]
    print(details["animal"])

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

class MyError(Exception):
    def __init__(self, message, animal):
        self.message = message
        self.animal = animal
    def __str__(self):
        return self.message

এই উদাহরণ চেষ্টা করুন

class InvalidInputError(Exception):
    def __init__(self, msg):
        self.msg = msg
    def __str__(self):
        return repr(self.msg)

inp = int(input("Enter a number between 1 to 10:"))
try:
    if type(inp) != int or inp not in list(range(1,11)):
        raise InvalidInputError
except InvalidInputError:
    print("Invalid input entered")

এক বনাম আরো বৈশিষ্ট্য ব্যবহার করা হয় তাহলে ডিফল্টভাবে ব্যতিক্রমগুলি কীভাবে কাজ করে তা দেখুন (ট্র্যাসব্যাকগুলি বাদ দেওয়া হয়েছে):

>>> raise Exception('bad thing happened')
Exception: bad thing happened

>>> raise Exception('bad thing happened', 'code is broken')
Exception: ('bad thing happened', 'code is broken')

সুতরাং আপনি একটি ব্যতিক্রম " আপেক্ষিক টেমপ্লেট ", একটি ব্যতিক্রম হিসাবে কাজ করতে পারে একটি সামঞ্জস্যপূর্ণ ভাবে থাকতে পারে:

>>> nastyerr = NastyError('bad thing happened')
>>> raise nastyerr
NastyError: bad thing happened

>>> raise nastyerr()
NastyError: bad thing happened

>>> raise nastyerr('code is broken')
NastyError: ('bad thing happened', 'code is broken')

এই এই subclass সঙ্গে সহজে করা যাবে

class ExceptionTemplate(Exception):
    def __call__(self, *args):
        return self.__class__(*(self.args + args))
# ...
class NastyError(ExceptionTemplate): pass

এবং যদি আপনি ডিফল্ট __str__ মত প্রতিনিধিত্বটি পছন্দ করেন না তবে ExceptionTemplate ক্লাসে __str__ পদ্ধতি যুক্ত করুন, যেমন:

    # ...
    def __str__(self):
        return ': '.join(self.args)

এবং আপনি হবে

>>> raise nastyerr('code is broken')
NastyError: bad thing happened: code is broken

হয়তো আমি প্রশ্ন মিস করেছি, কিন্তু কেন না:

class MyException(Exception):
    pass

সম্পাদনা করুন: কিছু ওভাররাইড (অথবা অতিরিক্ত আর্গুমেন্ট পাস), এটি করুন:

class ValidationError(Exception):
    def __init__(self, message, errors):

        # Call the base class constructor with the parameters it needs
        super(ValidationError, self).__init__(message)

        # Now for your custom code...
        self.errors = errors

এভাবে আপনি দ্বিতীয় e.errors ত্রুটির বার্তাগুলি e.errors করতে পারেন এবং পরে এটি e.errors দিয়ে পেতে পারেন

পাইথন 3 হালনাগাদ: পাইথন 3+ এ আপনি super() এর সামান্য কম কম্প্যাক্ট ব্যবহারটি ব্যবহার করতে পারেন:

class ValidationError(Exception):
    def __init__(self, message, errors):

        # Call the base class constructor with the parameters it needs
        super().__init__(message)

        # Now for your custom code...
        self.errors = errors

পাইথন 3.8 (2018, https://docs.python.org/dev/whatsnew/3.8.html ) হিসাবে, প্রস্তাবিত পদ্ধতি এখনও রয়েছে:

class CustomExceptionName(Exception):
    """Exception raised when very uncommon things happen"""
    pass

দস্তাবেজ ভুলবেন না দয়া করে, কেন একটি কাস্টম ব্যতিক্রম নিরপেক্ষ হয়!

যদি আপনার প্রয়োজন হয় তবে আরও ডেটা দিয়ে ব্যতিক্রমগুলির জন্য যেতে হবে:

class CustomExceptionName(Exception):
    """Still an exception raised when uncommon things happen"""
    def __init__(self, message, payload=None):
        self.message = message
        self.payload = payload # you could add more args
    def __str__(self):
        return str(self.message) # __str__() obviously expects a string to be returned, so make sure not to send any other data types

এবং তাদের মত আনা:

try:
    raise CustomExceptionName("Very bad mistake.", "Forgot upgrading from Python 1")
except CustomExceptionName as error:
    print(str(error)) # Very bad mistake
    print("Detail: {}".format(self.payload)) # Detail: Forgot upgrading from Python 1

payload=None এটি pickle সক্ষম করতে গুরুত্বপূর্ণ। এটি ডাম্প করার আগে, আপনাকে error.__reduce()__ কল করতে হবে error.__reduce()__ । লোড হচ্ছে প্রত্যাশিত হিসাবে কাজ করবে।

আপনি যদি কিছু বাইরের কাঠামোতে স্থানান্তরিত হওয়ার জন্য অনেক তথ্য প্রয়োজন হলে পাইথন return স্টেটমেন্ট ব্যবহার করে সমাধান খোঁজার জন্য আপনাকে তদন্ত করতে হবে। এটা আমার কাছে আরও পরিষ্কার / আরো পাইথনিক বলে মনে হচ্ছে। উন্নত ব্যতিক্রমগুলি জাভাতে ব্যাপকভাবে ব্যবহৃত হয়, যা কখনও কখনও বিরক্তিকর হতে পারে, যখন ফ্রেমওয়ার্ক ব্যবহার করে এবং সমস্ত সম্ভাব্য ত্রুটিগুলি ধরতে পারে।





exception