পাইথন বিমূর্ত শ্রেণিতে কীভাবে বিমূর্ত বৈশিষ্ট্য তৈরি করা যায়


118

নিম্নলিখিত কোডে, আমি একটি বেস বিমূর্ত শ্রেণি তৈরি করি Base। আমি সম্পত্তি Baseসরবরাহের জন্য উত্তরাধিকারসূত্রে প্রাপ্ত সমস্ত শ্রেণিগুলি চাই name, তাই আমি এই সম্পত্তিটিকে একটি করে দিয়েছি @abstractmethod

তারপরে আমি একটি সাবক্লাস তৈরি করেছিলাম , যার Baseনাম Base_1কিছু কার্যকারিতা সরবরাহ করা হয়, তবে এখনও বিমূর্ত থাকে। এখানে কোনও nameসম্পত্তি নেই Base_1, তবে তবুও পাইথন ত্রুটি ছাড়াই class শ্রেণির কোনও বস্তুকে তাত্পর্যপূর্ণ করে। একজন কীভাবে বিমূর্ত বৈশিষ্ট্য তৈরি করতে পারে?

from abc import ABCMeta, abstractmethod
class Base(object):
    __metaclass__ = ABCMeta
    def __init__(self, strDirConfig):
        self.strDirConfig = strDirConfig

    @abstractmethod
    def _doStuff(self, signals):
        pass

    @property    
    @abstractmethod
    def name(self):
        #this property will be supplied by the inheriting classes
        #individually
        pass


class Base_1(Base):
    __metaclass__ = ABCMeta
    # this class does not provide the name property, should raise an error
    def __init__(self, strDirConfig):
        super(Base_1, self).__init__(strDirConfig)

    def _doStuff(self, signals):
        print 'Base_1 does stuff'


class C(Base_1):
    @property
    def name(self):
        return 'class C'


if __name__ == '__main__':
    b1 = Base_1('abc')  

Gotcha: আপনি প্রসাধক ব্যবহার করতে ভুলে যান তাহলে @propertyclass C, nameএকটি পদ্ধতি প্রত্যাবর্তন করবে।
কেভিনার্পে

উত্তর:


117

পাইথন ৩.৩ যেহেতু একটি বাগ ঠিক করা হয়েছিল যার অর্থ property()সাজসজ্জাকারীকে অ্যাবস্ট্রাক্ট পদ্ধতিতে প্রয়োগ করার সময় এখন সঠিকভাবে বিমূর্ত হিসাবে চিহ্নিত করা যায়।

দ্রষ্টব্য: অর্ডার বিষয়গুলি, আপনাকে @propertyআগে ব্যবহার করতে হবে@abstractmethod

পাইথন ৩.৩++: ( পাইথন ডক্স ):

class C(ABC):
    @property
    @abstractmethod
    def my_abstract_property(self):
        ...

পাইথন 2: ( পাইথন ডক্স )

class C(ABC):
    @abstractproperty
    def my_abstract_property(self):
        ...

1
@ জেমস কীভাবে এটি অজগর 2 এর জন্য সামঞ্জস্যপূর্ণ করবেন?
himanshu219

@James আসলে আমি উভয় জন্য বোঝানো কিন্তু কিছু মনে করবেন না আমি আপনার সমাধান উপর ভিত্তি করে একটি উত্তর পোস্ট
himanshu219

45

পাইথন ৩.৩ অবধি আপনি বাসা বাঁধতে পারবেন না @abstractmethodএবং @property

@abstractpropertyবিমূর্ত বৈশিষ্ট্য ( ডক্স ) তৈরি করতে ব্যবহার করুন ।

from abc import ABCMeta, abstractmethod, abstractproperty

class Base(object):
    # ...
    @abstractproperty
    def name(self):
        pass

কোডটি এখন সঠিক ব্যতিক্রম উত্থাপন করে:

ট্রেসব্যাক (সবচেয়ে সাম্প্রতিকতম কল সর্বশেষ):
  ফাইল "foo.py", লাইন 36, ইন 
    বি 1 = বেস_1 ('এবিসি')  
প্রকারের ত্রুটি: বিমূর্ত পদ্ধতির নাম সহ বিমূর্ত শ্রেণি বেস_1 ইনস্ট্যান্ট করতে পারে না

42
প্রকৃতপক্ষে এই উত্তরটি অল্প অজগরগুলির জন্য ভুল: ৩.৩ থেকে ওপির @abstractpropertyমতো সংমিশ্রনের পক্ষে অবহেলা করা হয়।
উড়ন্ত ভেড়া



তাই 3.3 অবধি, কেবলraise NotImplementedError
সাওমির লেনার্ট

আমরা কী অবজেক্ট থেকে উত্তরাধিকারী হতে পারি এবং এখনও এবিসি টিকা ব্যবহার করতে পারি? উদাহরণ হিসাবে প্রদর্শিত হিসাবে এটি কাজ করবে?
সনথোষ কুমার

3

উপরে জেমস উত্তরের উপর ভিত্তি করে

def compatibleabstractproperty(func):

    if sys.version_info > (3, 3):             
        return property(abstractmethod(func))
    else:
        return abstractproperty(func)

এবং এটি একটি সজ্জা হিসাবে ব্যবহার করুন

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