简体   繁体   中英

A class property does not make it to the instance of the inheriting class?

I have defined a class property by defining an attribute with @property decorator in a metaclass, as proposed in this SO answer .

As I have only access at the class definition (that will inherits from the metaclass) after it has been defined, I am making it inheriting afterwards, thanks to the trick given in above mentioned SO answer.

I would like the class property defined to be available in both the inheriting class and its instances. But I don't succeed to have it in its instances.

So, let's review my current code:

class TopLevel(type):
    """ TopLevel metaclass defining class properties. """
    @property
    def depth(cls) -> int:
        return cls._depth

class OtherClass:
    """ Class that will inherit from 'TopLevel' after it has been defined.
        Dummy implementation."""
    def __init__(self, var):
        self.var = var


# Making 'Otherclass' inheriting from metaclass 'TopLevel' to have available
# as class properties 'depth'.
# As per https://stackoverflow.com/a/5121381/4442753
OtherClass = TopLevel(OtherClass.__name__,
                      OtherClass.__bases__,
                      dict(OtherClass.__dict__))
# Set a value to '_depth'
OtherClass._depth = 3

# Check OtherClass has 'depth' class property
OtherClass.depth
Out[6]: 3

# Instanciate OtherClass: instance has no 'depth' attribute?
otherclass = OtherClass(4)
otherclass.depth
Traceback (most recent call last):

  File "/tmp/ipykernel_748533/2343605532.py", line 1, in <module>
    otherclass.depth

AttributeError: 'OtherClass' object has no attribute 'depth'

Can this be achieved?

Here is a solution:

class TopLevel(type):
    """ TopLevel metaclass defining class properties. """
    @property
    def depth(cls) -> int:
        return cls._depth

class OtherClass:
    """ Class that will inherit from 'TopLevel' after it has been defined.
        Dummy implementation."""
    def __init__(self, var):
        self.var = var

# explicitely add property to OtherClass.__dict__
d = dict(OtherClass.__dict__)
d.update({"depth": TopLevel.depth})

OtherClass = TopLevel(OtherClass.__name__,
                      OtherClass.__bases__,
                      d)

OtherClass._depth = 3

otherclass = OtherClass(4)
print(otherclass.depth)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM