Search code examples
pythonpython-2.7abstract-classabc

Define private variable of class as abstract


I want to know what is the correct way to make my class's private variables as abstract. Let me summarize the properties of my variable:

  • Class variable
  • private
  • abstract

Structure of my classes is like:

from abc import ABCMeta

class AbstractClass(ABCMeta):
    __private_abstract_property = None   # Needs this as private abstract class variable
    # ... some functions


class ParentClass(AbstractClass):   # inherits `AbstractClass`
    # .. some more functions


class ChildClass1(ParentClass):    # inherits `ParentClass`
    __private_abstract_property = 'value1'   # value to be initialized here


class ChildClass2(ParentClass):    # inherits `ParentClass`
    __private_abstract_property = 'value2'

What is the correct way to achieve this?

One way is to use abc.abstractproperty decorator as:

class AbstractClass(ABCMeta):
    @abstractproperty
    def __private_abstract_property(self):
        ...

Or, as mentioned in answers to Abstract Attributes in Python as:

class AbstractClass(ABCMeta):
    __private_abstract_property = NotImplemented

I want to know the right way to achieve this (any approach even apart from what I mentioned is welcomed).


Edit: Here is some description of what I am trying to do:

  • I have a manager AbstractClass which has some set operation related to the database. It should be abstract as I do not want any direct object of this class. Also it has some functions with no definition

  • ParentClass is derived from the AbstractClass. It will have some set of function related to fetching particular items from database. Again this class also don't know about the database it is dealing with.

  • The ChildClass will be actually having the database engine with which it should interact with. As there can be different engines holding same kind of information, I will set the connection name here and based on this connection as source, ParentClass's function will fetch information from database. Also, ChildClass can have additional functions apart from ParentClass


Solution

  • There is no privacy model in Python. Double-underscore names are not private in the sense that a Java or C# name is private; such names are class private.

    Class private means they are protected (by prefixing their name with the class name) from accidental overriding in a subclass. This means that there is absolutely no point in putting double-underscore names in an abstract class; subclasses should never use the exact same name.

    See the Reserved classes of identifiers section part of the reference documentation:

    __*
    Class-private names. Names in this category, when used within the context of a class definition, are re-written to use a mangled form to help avoid name clashes between “private” attributes of base and derived classes.

    You should not put anything private in a abstract base class anyway. ABCs are akin to interfaces, documenting the public API subclasses should provide.

    So, even if you gave names a single leading underscore (signalling, by convention only, that a name is part of the internal implementation and can't be relied upon to remain available in other implementations or future versions), these should not be part of an ABC; it is not the purview of an abstract base class to dictate how subclasses implement the methods and properties proscribed.