问题描述
|
假设有一个名为get_pack()的库函数,该函数返回Pack对象:
class Pack(object):
def __init__(self,name,weight):
self.name = name
self.weight = weight
...
我想做的就是将此对象包装到我的对象中,这就是说说CommercialPack,它具有几个有用的功能:
class CommercialPack(Pack):
def get_delivery_price(self,distance):
return self.weight * PER_KM_PRICE * distance
...
然后创建一个返回CommercialPack而不是Pack的函数。在某些其他语言(例如Delphi或Java)中,您可以即时键入该对象。所以我想有这样的事情:
def get_commercial_pack():
return CommercialPack(get_pack())
然后您便拥有了所有您需要的东西。因为我希望我的CommercialPack对象具有Pack对象具有的所有属性和功能。我只想将其包装在我的新班级中。基本上我不想做这样的事情:
class CommercialPack(object):
def __init__(self,pack):
self.name = pack.name
self.weight = pack.weight
...
要么
class CommercialPack(object):
def __init__(self,pack):
self.pack = pack
我正在寻找一种优雅的解决方案,而不是像我所说的那样,使用某种类型转换或我可以在Python中优雅完成的任何事情。
非常感谢。
解决方法
也许像这样
class CommercialPack(object):
def __init__(self,pack):
self.__dict__.update(pack.__dict__)
如果您不介意在套件和商业套件之间共享状态,则可以执行此操作
class CommercialPack(object):
def __init__(self,pack):
self.__dict__ = pack.__dict__
在您的示例中应该没问题,因为您没有保留对pack对象的任何其他引用
例如。
PER_KM_PRICE = 100
class Pack(object):
def __init__(self,name,weight):
self.name = name
self.weight = weight
class CommercialPack(Pack):
def __init__(self,pack):
self.__dict__ = pack.__dict__
def get_delivery_price(self,distance):
return self.weight * PER_KM_PRICE * distance
def get_pack():
return Pack(\"pack\",20)
cp = CommercialPack(get_pack())
print cp.get_delivery_price(3)
,这对您有用吗?
#!/usr/bin/python
PER_KM_PRICE = 10
class Pack(object):
def __init__(self,weight):
self.name = name
self.weight = weight
def test_fn(self):
print \"test\"
class CommercialPack(Pack):
def __init__(self,pack):
self.pack = pack
def get_delivery_price(self,distance):
return self.weight * PER_KM_PRICE * distance
def __getattr__(self,attr):
return getattr(self.pack,attr)
您可以这样使用:
>>> p = Pack(10,20)
>>> cp = CommercialPack(p)
>>> cp.weight
20
>>> cp.get_delivery_price(10)
2000
>>> cp.test_fn()
test
,注意:这是该答案在附近的副本(希望在上面。)
因此,您不想复制无聊的Pack字段列表,而是要添加一些内容。有一种简单的方法可以使用ѭ10来委派未知名称的解析:
class CommercialPack(object):
def __init__(self,pack):
self.pack = pack
self.bar = 10
class CommercialPack(object):
def __init__(self,pack):
self.pack = pack
self.bar = 10
def __getattr__(self,name):
return getattr(self.pack,name) # not called for bar!
现在魔术起作用了:
>>> p = Pack(\'I am foo\')
>>> p.foo
\'I am foo\'
>>> cp = CommercialPack(p)
>>> cp.foo
\'I am foo\'
>>> cp.bar
10
>>> _
因此,您可以向CommercialPack
添加方法和任何其他属性,并透明地访问Pack
的那些属性。
请注意,如果添加的名称已经存在于Pack
中,则CommercialPack
\的属性将遮盖相同名称的Pack
\'s的属性。但是您始终可以通过pack
属性访问它。