我在某个地方定义了一个基类,它可以由一些用户扩展。
现在我想访问该用户在其子类中可能定义的变量,这样我就可以用它做一些事情
我试图通过使用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
类不应该知道它的子类变量,而应该只访问它们。
建立在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
一种可能的解决方案是(绕过基类构造过程中发生的错误(:
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)
....
`
我想这更简单,更符合条件。。
但我仍在等待一个可能更好的解决方案!