अजगर अमूर्त वर्गों में अमूर्त गुण कैसे बनाएं


118

निम्नलिखित कोड में, मैं एक आधार सार वर्ग बनाता हूं Base। मुझे वह सभी वर्ग चाहिए जो संपत्ति Baseप्रदान करने के लिए विरासत में मिले name, इसलिए मैंने इस संपत्ति को ए @abstractmethod

फिर मैंने एक उप-वर्ग बनाया Base, जिसे कहा जाता है Base_1, जो कुछ कार्यक्षमता की आपूर्ति करने के लिए है, लेकिन अभी भी सार है। इसमें कोई nameसंपत्ति नहीं है Base_1, लेकिन फिर भी अजगर बिना किसी त्रुटि के उस वर्ग की एक वस्तु को उकसाता है। सार गुण कैसे बनता है?

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')  

पकड़ लिया: आप डेकोरेटर का उपयोग करने भूल जाते हैं @propertyमें class C, nameएक विधि पर लौट जाएगा।
केविनर्पपे नोव

जवाबों:


117

चूंकि पायथन 3.3 एक बग तय किया गया था जिसका अर्थ यह है कि property()डेकोरेटर को अब अमूर्त के रूप में सही तरीके से पहचाना जाता है।

नोट: आदेश मायने रखता है, आपको @propertyपहले उपयोग करना होगा@abstractmethod

पायथन 3.3+: ( अजगर डॉक्स ):

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

अजगर 2: ( अजगर डॉक्स )

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

1
@ जेम्स यह अजगर 2 और साथ ही कैसे संगत करें?
himanshu219

@ जेम्स वास्तव में मैं दोनों के लिए अभिप्राय रखता हूं, लेकिन कभी-कभार मैंने आपके समाधान के आधार पर एक उत्तर पोस्ट किया
himanshu219

45

पायथन 3.3 तक , आप घोंसला नहीं बना सकते हैं @abstractmethodऔर @property

@abstractpropertyअमूर्त गुण ( डॉक्स ) बनाने के लिए उपयोग करें ।

from abc import ABCMeta, abstractmethod, abstractproperty

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

कोड अब सही अपवाद उठाता है:

ट्रेसबैक (सबसे हालिया कॉल अंतिम):
  फ़ाइल "foo.py", पंक्ति 36, में 
    b1 = Base_1 ('abc')  
TypeError: अमूर्त विधियों के नाम के साथ सार वर्ग Base_1 को तत्काल नहीं कर सकता

42
वास्तव में युवा अजगर के लिए यह उत्तर गलत है: 3.3 के बाद से, @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()
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.