我正在尝试将类属性从一个类复制到另一个类
d = {1:'one', 2:'two'}
class X(object):
a = 1
b = 2
我需要定义类Y,以便满足以下条件:
assert Y.a =='one' and Y.b=='two'
实现这一目标的一种方法如下:
attrDict = {attr:d[getattr(X,attr)] for attr in dir(X) if isinstance(getattr(X,attr), int)}
# attrDict is {'a':'one', 'b':'two'}
class Y(X):
def __init__(self):
self.copyOver()
@classmethod
def copyOver(klass):
[setattr(klass, k,v) for k,v in attrDict.iteritems()]
y = Y() # Y.a = 1 unless this runs
assert Y.a == 'one' and Y.b == 'two'
但是,在实际应用中实例化可能很昂贵:没有可能实现这个目标吗?
换句话说, 我用什么内置来更新类属性而不需要实例化它的对象 ?
class Y(X):
#TODO: setattr all key value pairs in attrDict on the class Y, not on instances of it.
#TODO: Do it without requiring to instantiate an object of class Y
答案 0 :(得分:1)
与您所拥有的相似但没有在其间创建字典:
In [120]: d = {1:'one', 2:'two'}
...: class X(object):
...: a = 1
...: b = 2
...:
In [121]: class Y(X):
...: @classmethod
...: def change_me(cls):
...: for k, v in X.__dict__.items():
...: if v in d:
...: setattr(cls, k, d[v])
...:
In [122]: Y.a
Out[122]: 1
In [123]: Y.change_me()
In [124]: Y.a
Out[124]: 'one'
In [125]: X.a
Out[125]: 1
这是一个使用元类的版本,它解决了您必须明确运行 classmethod 的问题(假设是python3):
In [145]: d = {1:'one', 2:'two'}
...: class X(object):
...: a = 1
...: b = 2
...:
...:
In [146]: class ChangeOnCreation(type):
...: def __init__(cls, name, bases, attr_dict):
...: super().__init__(name, bases, attr_dict)
...: for subs in bases:
...: for k, v in subs.__dict__.items():
...: if v in d:
...: setattr(cls, k, d[v])
...:
In [147]: class Y(X, metaclass=ChangeOnCreation):
...: pass
...:
In [148]: Y.a
Out[148]: 'one'
In [149]: X.a
Out[149]: 1
答案 1 :(得分:0)
什么阻止您直接在类型(类)上分配值? e.g:
class X(object):
a = 1
b = 2
d = {1: 'one', 2: 'two'}
class Y(X): pass
for k in dir(Y):
val = getattr(Y, k)
try:
if val in d:
setattr(Y, k, d[val])
except TypeError:
pass # ignore the types that cannot be in our `d`
assert Y.a == "one" and Y.b == "two"