0

是否可以跨多个子类在基类内的子类中动态创建/设置变量而不影响其他子类?

例如,在此处获取此代码:

class Base:
    @classmethod
    def __init__(cls,v):
        cls.v=v

class sub1(Base):
    Base.__init__(1)

class sub2(Base):
    Base.__init__(5)

在该代码中,当sub1被创建时,它的v属性等于1. 但是当sub2被创建时,两者的属性v都变成了。我想我可能知道这是为什么。我假设基类的实际并不是设置子类的属性,而是它自己的属性。然后在子类中继承该属性。我的问题是:如何使用这种继承来设置子类的属性,而不是继承的基类的属性。sub1sub25@classmethod

换句话说,我希望能够使用类似的结构,如果可能的话(或至少是一个简单的结构),以完成在子类中设置特定于子类的属性,而不是简单地从基类全局继承.

这甚至可能吗?

4

1 回答 1

0

我不知道它是否可以通过任何其他方式轻松完成,但我自己使用元类提出了一个解决方案。

解决方案:

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)
于 2018-01-24T03:54:42.577 回答