3

I have googled around for some time, but what I got is all about instance property rather than class property. For example, this is the most-voted answer for question from stackoverflow

class C(ABC):
    @property
    @abstractmethod
    def my_abstract_property(self):
        return 'someValue'

class D(C)
    def my_abstract_property(self):
        return 'aValue'

class E(c)
   # I expect the subclass should have this assignment,
   # but how to enforce this?
   my_abstract_property = 'aValue'  

However, that is the instance property case, not my class property case. In other words, calling
D.my_abstract_property will return something like <unbound method D.my_abstract_property>. Returning 'aValue' is what I expected, like class E.

3
  • 1
    So you want a class variable that is constant for all subclass instances? Commented Mar 6, 2020 at 10:27
  • Yes. That's indeed what I want. Commented Mar 6, 2020 at 10:29
  • Not exactly. I do want a class variable, but I want it to be constant for all its "instances", not "subclass". I expect all subclass of "C" to have a class property with the same name, but value can vary. Commented Mar 6, 2020 at 10:45

3 Answers 3

1

Based on your example and comment to my previous reply, I've structured the following which works with ABC. :

from abc import ABC

class C(ABC):
    _myprop = None

    def __init__(self):
        assert self._myprop, "class._myprop should be set"

    @property
    def myprop(self):
        return self._myprop


class D(C):
    _myprop = None

    def __init__(self):
        super().__init__()


class E(C):
    _myprop = 'e'

    def __init__(self):
        super().__init__()


e = E()
print(e.myprop)

d = D()
print(d.myprop)

You are correct that there is no Python pre-scan that will detect another developer has not assigned a value to a class variable before initializing. The initializer will take care of notifying pretty quickly in usage.

Sign up to request clarification or add additional context in comments.

1 Comment

Almost there. I expect "C.myprop" to be "None", and each of C's subclass has its own value of "myprop". In your code, D still needs to do one more function call to set its own value. Can the developer of subclass assign "myprop" in the implementation of his subclass without a external function call?
0

You can use @classmethod decorator.

1 Comment

I tried, it seems not working. If c is declared with abc.ABCMeta, and have a method called "my_abstract_property" decorated by @classmethod, and D inherets C, calling 'D.my_abstract_property` returns '<bound method ABCMeta.my_abstract_property of <class 'main.D'>>'. Can you share some code that can work correctly?
0

I come up with a tricky workaround.

class C(object):
    myProp = None
    def __init__(self):
        assert self.myProp, 'you should set class property "name"'

class D(C):

    def __init__(self):
        C.__init__(self)

class E(C):
    myProp = 'e'
    def __init__(self):
        C.__init__(self)

print(D.myProp)
print(E.myProp)

But it still has some problems:

  1. D.myProp will not raise any exception to warn the developer about the constraint (assigning myProp as its class property), until the developer initialize an instance of his class.
  2. abc module cannot work with this solution, which means loss of lots of useful features of that module

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.