[英]Set Subclass Variables/Attributes from Within Base Class
Is it possible to dynamically create/set variables within a subclass within the base class across multiple subclasses without affecting the other subclasses? 是否可以在多个子类之间的基类的子类中动态创建/设置变量,而不影响其他子类?
For example, take this code here: 例如,在这里使用以下代码:
class Base:
@classmethod
def __init__(cls,v):
cls.v=v
class sub1(Base):
Base.__init__(1)
class sub2(Base):
Base.__init__(5)
In that code, when sub1
is created, its v
attribute is equal to 1
. 在该代码中,创建sub1
时,其v
属性等于1
。 But when sub2
is created, the v
attribute of both sub1
and sub2
becomes 5
. 但是,当创建sub2
时, sub1
和sub2
的v
属性都变为5
。 I think I might know why this is. 我想我可能知道为什么。 I assume the @classmethod
of the base class is not actually setting the attribute of the subclass, but instead its own attribute. 我假设基类的@classmethod
实际上不是设置子类的属性,而是设置其自己的属性。 Then that attribute is inherited in the subclasses. 然后,该属性在子类中继承。 My question is: how can I use this kind of inheritance to set attributes of subclasses, not attributes of the base class which are inherited. 我的问题是:如何使用这种继承来设置子类的属性,而不是继承的基类的属性。
In other words, I would like to be able to use a similar structure, if possible (or at least a simple one) in order to accomplish setting attributes in subclasses that are specific to the subclasses and are not simply globally inherited from the base class. 换句话说,我希望能够使用类似的结构(如果可能的话)(或至少是一个简单的结构),以便在特定于子类的子类中完成设置属性,而不是简单地从基类全局继承。
Is this even possible? 这有可能吗?
I don't know if it can be easily accomplished any other way, but I've come up with a solution myself using a metaclass. 我不知道是否可以通过其他任何方式轻松实现,但是我自己使用元类提出了一个解决方案。
Solution: 解:
class MetaBase(type):
def __init__(cls, name, bases, namespace):
super(MetaBase, cls).__init__(name, bases, namespace)
if '_superclass' in namespace: # A special attribute to distinguish between superclasses and subclasses
if '_attrnames' not in namespace:
raise AttributeError('"_attrnames" needs to be defined as a class attribute in a superclass.')
else:
if 'classvars' in namespace: # Allow for define all required class attributes in one iterable attribute
for attrname, attr in zip(getattr(cls.__mro__[1], '_attrnames'), getattr(cls, 'classvars')): # Get all the varnames in the superclass's "varnames", as well as the values
setattr(cls, attrname, attr)
namespace[attrname] = attr
delattr(cls, 'classvars')
else:
for attrname in getattr(cls.mro()[1], '_attrnames'):
if attrname not in namespace:
raise AttributeError('"%s" not defined, but is required.' % attrname)
class Base(metaclass=MetaBase):
_superclass = True # The value of this attribute doesn't matter
_attrnames = ('a','b','c')
class Sub1(Base):
a = 1
b = 2
c = 3
class Sub2(Base):
classvars = (1, 2, 3)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.