arash javanmard
arash javanmard

Reputation: 1387

Python abstract attribute and inheritance

Say I have the following code:

class Archive(object):
    """ Archiv-File wrapper """
    READ_MODE = 0
    WRITE_MODE = 1

    def __init__(self, file_):
        self.file_ = file_
        self._mode = None

    @property
    def mode(self):
        return self._mode

    @mode.setter
    def mode(self, value):
        self._mode = value

    def open(self, mode="r", pwd=None):
        raise NotImplemented("Subclasses should implement this method!")

    def close(self):
        raise NotImplemented("Subclasses should implement this method!")

################################################

class GzipGPGArchive(Archive):
    READ_MODE = 'r:gz'  # Open for reading with gzip compression.
    WRITE_MODE = 'w:gz'  # Open for gzip compressed writing.
    SUFFIX = "tar.gz.gpg"

    def __init__(self, *args, **kwargs):
        super(GzipGPGArchive, self).__init__(*args, **kwargs)

    @mode.setter # This causes unresolved reference
    def mode(self, value):
        # do internal changes
        self._mode = value

    def open(self):
        pass

    def close(self):
        pass

so know what is the best pythonic way to override the setter and getter method of the Abstract class attribute mode.

Overriding @mode.setter in the sub-class GzipGPGArchive causes unresolved reference!

Upvotes: 1

Views: 3574

Answers (1)

Andrejs Cainikovs
Andrejs Cainikovs

Reputation: 28474

First of all, there is no such thing as abstract attributes in Python. You can achieve abstraction, however, by using abc module. Perhaps it is not really "pythonic", but it works.

This is the minimal example with inheritance and abstraction. Use it as as template:

from abc import ABCMeta, abstractmethod

class Mother(metaclass=ABCMeta):

    @abstractmethod
    def method_(self):
        pass

    @property
    @abstractmethod
    def property_(self):
        return -1

    @property_.setter
    @abstractmethod
    def property_(self, value):
        pass

class Daughter(Mother):

    def __init__(self):
        self.value_ = 0

    def method_(self):
        print(self.value_)

    @property
    def property_(self):
        return = self.value_

    @property_.setter
    def property_(self, value):
        self.value_ = value

Upvotes: 3

Related Questions