从基础 Class 中设置子类 Variables/Attributes
Set Subclass Variables/Attributes from Within Base Class
是否可以动态地 create/set 一个子 class 中的变量 class 跨多个子 class 基 class 而不影响其他子classes?
例如,把这段代码放在这里:
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
被创建时,sub1
和sub2
的v
属性都变成了5
。我想我可能知道这是为什么。我假设基础 class 的 @classmethod
实际上不是设置子 class 的属性,而是它自己的属性。然后该属性在 subclasses 中继承。我的问题是:如何使用这种继承来设置子 classes 的属性,而不是继承的基 class 的属性。
换句话说,如果可能(或至少是一个简单的结构),我希望能够使用类似的结构来完成子 classes 中特定于subclasses 并且不是简单地全局继承自基础 class.
这可能吗?
我不知道是否可以通过其他方式轻松完成,但我自己使用元类提出了一个解决方案。
解决方案:
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)
是否可以动态地 create/set 一个子 class 中的变量 class 跨多个子 class 基 class 而不影响其他子classes?
例如,把这段代码放在这里:
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
被创建时,sub1
和sub2
的v
属性都变成了5
。我想我可能知道这是为什么。我假设基础 class 的 @classmethod
实际上不是设置子 class 的属性,而是它自己的属性。然后该属性在 subclasses 中继承。我的问题是:如何使用这种继承来设置子 classes 的属性,而不是继承的基 class 的属性。
换句话说,如果可能(或至少是一个简单的结构),我希望能够使用类似的结构来完成子 classes 中特定于subclasses 并且不是简单地全局继承自基础 class.
这可能吗?
我不知道是否可以通过其他方式轻松完成,但我自己使用元类提出了一个解决方案。
解决方案:
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)