假设有一个名为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
...
OR
class CommercialPack(object):
def __init__(self, pack):
self.pack = pack
我正在寻找一个优雅的解决方案,就像我说的那样,某种类型的演员或我在Python中可以优雅地做的任何事情。
非常感谢。
答案 0 :(得分:4)
这对你有用吗?
#!/usr/bin/python
PER_KM_PRICE = 10
class Pack(object):
def __init__(self, name, 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
答案 1 :(得分:2)
也许是这样的
class CommercialPack(object):
def __init__(self, pack):
self.__dict__.update(pack.__dict__)
如果你不介意在包和商品包之间共享状态,你甚至可以这样做
class CommercialPack(object):
def __init__(self, pack):
self.__dict__ = pack.__dict__
在您的示例中应该没问题,因为您没有保留对包对象的任何其他引用
例如
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)
答案 2 :(得分:1)
注意:这是附近this answer的副本(希望在上面。)
所以你不想复制Pack的字段的无聊列表,但想要添加一点。有一个easy way to delegate resolution of unknown names使用__getattr__
:
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
的属性。但您始终可以通过pack
属性访问它。