我有一个容器类的实例,它作为其他几个实例的基础。它在示例中称为data0
。我希望能够制作副本,然后更新副本的一些成员。
是的,可以使用copy
模块完成,创建副本并为成员分配新值。但是如果容器类是不可变的呢?
我希望能够实现将类转换为映射(keys
和__getitem__
)并使__init__
接受基类加上一些修改所需的内容。这可能是因为您可以更新字典的方式:
x = {'a': 0, 'b': 1, 'c': 2}
y = {'b': 7}
z = {**x, 'b': 7}
print(z) # {'a': 0, 'b': 7, 'c': 2}
所以我希望能够做到的是:
data3 = Container(**data0, b=7)
print(data3)
这是我试过的:
class Container:
KEYS = ('a', 'b', 'c')
def __init__(self, a=None, b=None, c=None):
self._a = a
self._b = b
self._c = c
@property
def a(self):
return self._a
@property
def b(self):
return self._b
@property
def c(self):
return self._c
def keys(self):
return Container.KEYS
def __getitem__(self, key):
if key not in Container.KEYS:
raise KeyError(key)
return getattr(self, key)
def __str__(self):
return f'{self.__class__.__name__}(a={self.a}, b={self.b}, c={self.c})'
data0 = Container(a=1, b=2, c=3)
print(data0) # Container(a=1, b=2, c=3)
data1 = Container(**data0) # 'copy constructor'
print(data1) # Container(a=1, b=2, c=3)
data2 = Container(**{**data0, 'b':7})
print(data2) # Container(a=1, b=7, c=3)
最后一种方法有效,但很难看......
如上所述:我希望能够做到的是:
data3 = Container(**data0, b=7)
print(data3)
但这(可以理解)失败并显示错误消息
TypeError:type object为关键字参数' b'
获取了多个值
我该如何解决这个问题?或者是否有更明显的方法从更新成员的给定基础创建新实例?
或者是标准的方法,只是从具有所需值作为默认值的类继承?
class Container1(Container):
def __init__(self, a=1, b=2, c=3):
super().__init__(a=a, b=b, c=c)
data3 = Container1(b=7)
print(data3) # Container1(a=1, b=7, c=3)
这有点冗长,并且data3
的类型为Container1
......
我的尝试在python 3.5上的行为与在{3}}上的python 3.6不同。