如何从该类访问某个类的子类中定义的变量?

时间:2020-08-27 18:53:03

标签: python variables subclass metaclass

我在某个地方定义了一个基类,该基类可由某些用户扩展。

现在,我想访问该用户在其子类中可能定义的变量,以便我可以对其进行处理。

我尝试使用metaclass es

解决此问题

这里是示例设置:

class Meta(type):
    def __new__(cls, name, bases, attrs):
        clsobj = super().__new__(cls, name, bases, attrs)
        print(f'the name of this class is {clsobj.NAME.upper()}')
        return clsobj


class Base(metaclass=Meta):
    pass

class C1(Base):
    NAME = "C1"

if __name__ == "__main__":
    c1 = C1()

但是我遇到以下错误:

AttributeError: type object 'Base' has no attribute 'NAME'

Base类既不应了解其sublcass变量,而应仅访问它们。

2 个答案:

答案 0 :(得分:0)

一种可能的解决方案是(绕过在构造基类时发生的错误):

class Meta(type):
    def __new__(cls, name, bases, attrs):
        clsobj = super().__new__(cls, name, bases, attrs)
        if 'NAME' not in vars(clsobj):  # add these lines
            pass                        # add these lines (bypass mechanism)
        else:                           # add these lines
            print(f'the name of this class is {clsobj.NAME.upper()}')          
        return clsobj                   


class Base(metaclass=Meta):
    pass

class C1(Base):
    NAME = "C1"

if __name__ == "__main__":
    c1 = C1()

如果有多个感兴趣的变量,则if ... pass ... else ..变为:

clsattrs = vars(clsobj)
if 'VAR1' not in clsattrs or 'VAR2' not in clsattrs or 'VAR3' not in clsattrs ...:
    pass
else:
    function_on(VAR1)
    function_on(VAR2)
    function_on(VAR3)
    ....
`

我猜这更简单,更容易。

但是我仍在等待更好的解决方案!

答案 1 :(得分:0)

建立在OP的自我解答之上,但更为笼统(因此无需猜测属性名称):

class Meta(type):
    def __new__(cls, name, bases, attrs):
        clsobj = super().__new__(cls, name, bases, attrs)
        for attr, value in vars(clsobj).items():
            if not attr.startswith('__'):  # we probably want to ignore 'magic' attributes
                print(value)
        return clsobj