Python soyut sınıflarında soyut özellikler nasıl oluşturulur


118

Aşağıdaki kodda, bir temel soyut sınıf oluşturuyorum Base. Miras alan tüm sınıfların özelliği Basesağlamasını nameistiyorum, bu yüzden bu özelliği bir @abstractmethod.

Sonra bir alt sınıf oluşturdum Base, denilen Base_1, bazı işlevler sağlaması ama yine de soyut kalması amaçlanıyor. Orada hayır namemülkiyet Base_1, ama yine de piton bir hata olmadan bu sınıfın bir nesne instatinates. Soyut özellikler nasıl yaratılır?

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

Yakaladım: Eğer dekoratör kullanmayı unutursanız @propertyiçinde class C, namebir yönteme döner.
kevinarpe

Yanıtlar:


117

Python 3.3'ten bu yana, bir hata düzeltildi, yani property()dekoratör artık soyut bir yönteme uygulandığında doğru şekilde soyut olarak tanımlanıyor.

Not: Sipariş önemlidir, @propertyönce kullanmanız gerekir@abstractmethod

Python 3.3+: ( python belgeleri ):

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

Python 2: ( python belgeleri )

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

1
@James Python 2 ile nasıl uyumlu hale getirilir?
himanshu219

@James aslında ikisini de kastetmiştim ama boş ver senin çözümüne dayalı bir cevap gönderdim
himanshu219

45

Python 3.3'e kadar , @abstractmethodve @property.

@abstractpropertySoyut özellikler ( dokümanlar ) oluşturmak için kullanın .

from abc import ABCMeta, abstractmethod, abstractproperty

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

Kod artık doğru istisnayı ortaya çıkarıyor:

Geri izleme (en son çağrı son):
  "Foo.py" dosyası, satır 36, içinde 
    b1 = Base_1 ('abc')  
TypeError: Soyut yöntem adıyla Base_1 soyut sınıfı başlatılamıyor

42
aslında bu cevap genç pitonlar için yanlıştır: 3.3'ten beri, @abstractpropertyOP'ler gibi bir kombinasyon lehine kullanımdan kaldırılmıştır.
uçan koyun



yani 3.3'e kadar, sadeceraise NotImplementedError
Sławomir Lenart

nesneden miras alabilir ve yine de ABC ek açıklamalarını kullanabilir miyiz? Örnekte gösterildiği gibi çalışacak mı?
santhosh kumar

3

Yukarıdaki James cevabına göre

def compatibleabstractproperty(func):

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

ve onu bir dekoratör olarak kullan

@compatibleabstractproperty
def env(self):
    raise NotImplementedError()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.