如果我有两个类定义如下:
class A(object):
a = 10
class B(A):
b = 20
如果我创建一个对象:
c = A()
然后做:
c.__class__ = B
更改('升级')对象的类,维护主类属性和方法以及获取辅助类属性和方法是否是一种有效的方法?
如果为true,这只适用于我们更改对象的类继承自前一个类的情况?最好的问候。
更新:
提供更多背景信息。 我有以下类EmbrionDevice。
class EmbrionDevice(object):
def __init__(self, device_info, *args, **kwargs):
super(EmbrionDevice, self).__init__(*args, **kwargs)
# Serial number unique 64-bit address factory-set
self.shl = device_info['source_addr_long']
# 16-bit network address
self.my = device_info['source_addr']
# Node identifier
self.ni = device_info['node_identifier']
# Parent Address
self.pa = device_info['parent_address']
# Device type, 0-coordinator, 1-router, 2-End Device
self.dt = device_info['device_type']
# Device type identifier xbee or Digi device
self.dd = device_info['device_type_identifier']
# Device attributes summary in a dictionary
self.info = device_info
# Embrion future function
self.function_identifier = None
# Device state definition
self.state = DEV_STATE_CODES['embrion']
self.status = DEV_STATUS_CODES['no status']
我后来想要更改/升级到以下特定设备类之一:
class PassiveDevice(EmbrionDevice):
pass
class ActiveDevice(EmbrionDevice):
pass
基本上我想简化我的副本,避免复制所有属性。
答案 0 :(得分:2)
这不是更改实例对象类的有效方法,一个简单的例子可以证明它: -
class A(object):
a = 10
def __init__(self):
self.b = 20
self.c = 30
class B(A):
d = 35
def __init__(self):
self.x = 70
self.y = 80
c = A()
c.__class__ = B
print c
<__main__.B object at 0x02643F10>
所以现在c
是B类的实例,请尝试打印实例属性:
print c.x
print c.y
它说:
AttributeError: 'B' object has no attribute 'x'
答案 1 :(得分:1)
这绝对是一个黑客,这也是一个黑客攻击,但我发现它确实有点清洁:
In [1]: class A(object):
...: a = 10
...:
In [2]: class B(A):
...: b = 20
...:
In [3]: c = A()
In [4]: new_c = B()
In [5]: new_c.__dict__.update(c.__dict__.copy())
In [7]: repr(new_c)
Out[7]: '<__main__.B object at 0x102f32050>'
In [8]: new_c.b
Out[8]: 20
我不确定您的方法是否有效,但是,通过这种方式,您可以将旧对象的属性复制到已正确实例化的新对象中。如果您更改.__class__
,则无法保证旧变量将引用正确创建的新类对象,因为__init__()
,__new__()
等不会。跑。
要复制功能,这很难看......但是,你可以采取这样的方法:
In [18]: for name, obj in c.__class__.__dict__.iteritems():
....: if hasattr(obj, '__call__'):
....: # Copy the function.
....:
test
有各种hacky方法可以动态地向现有对象添加函数。他们都很难看,但是,他们可以找到here。
答案 2 :(得分:1)
你对什么是&#34;类属性&#34;有误解?在Python中 -
所有实例属性都保存在实例本身中:它具有__dict__
属性,该属性是一个字典,其中保留了由self.shl = device_info['source_addr_long']
等代码定义的所有属性。 (例如,此语句在该字典上创建shl
条目。
这些分配在__init__
方法中运行。如果通过分配对象的__class__
来更改对象的类,则它在某种意义上起作用:这是它的新类。新类可能已定义的方法现在是可访问的。但是上一课中设置的所有属性都是&#39; __init__
仍然存在,因为它们是在未更改的实例__dict__
上设置的。从我得到的,这可能正是你想要的 - 但请注意原始类的方法(以及类属性 - 即在类体本身上定义的属性)将是不可访问的,除非新类本身继承自原始类。如您所示的示例,这就是您正在做的事情,这种方法可能实际上适合您。
但要小心,并在交互式控制台上进行一些广泛的单元测试和测试。
替代方案可能是使用zope.interface - tis将允许您拥有一个对象,但是&#34;看起来像&#34;具有与代码的其他部分不同的属性和方法的对象,可能需要特定的接口。