我在某个地方定义了一个基类,该基类可由某些用户扩展。
现在,我想访问该用户在其子类中可能定义的变量,以便我可以对其进行处理。
我尝试使用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变量,而应仅访问它们。
答案 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