0

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

Community
  • 1
  • 1
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126

1 Answers1

3

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.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Ok, Let's say if I am okay with going with public variable (by convention), then I should be using `@abstractproperty` property decorator? – Moinuddin Quadri Nov 20 '16 at 17:25
  • 1
    @MoinuddinQuadri: yes, then you can document that you want an attribute with `@abstractproperty`. Note that there is no enforcement how things are implemented, only that the name is there, for both `@abstractmethod` and `@abstractproperty`. – Martijn Pieters Nov 20 '16 at 17:27
  • But in that case it will be instance variable, but I want it to be class variable. I made an edit in the question at the last. May be it will help you understand what I am trying to do – Moinuddin Quadri Nov 20 '16 at 17:36
  • 1
    @MoinuddinQuadri: no, abstract classes say nothing about instance vs class variables, just that the name needs to exist. – Martijn Pieters Nov 20 '16 at 17:36
  • 1
    @MoinuddinQuadri: your `ParentClass` and `ChildClass` classes are *implementations*. If `ParentClass` needs a certain name to be set on the class, then that's an implementation detail. That's not part of the public interface of the ABC. – Martijn Pieters Nov 20 '16 at 17:38