我想进行一个类组合,使组合类的实例变量成为组合的实例变量,但名称经过调整。
它的应用是在matplotlib中为绘图定义新对象。一个例子是,我希望有一个函数drawMyArrow
,它可以为箭头的头部、尾部和弧线绘制可能不同颜色(以及其他规格)的箭头。我希望能够通过drawMyArrow
中的关键字参数传递头部、尾部以及弧线的各种规格。我以前没有处理过类,但在网上读到这篇文章后,我相信解决我问题的最好方法是定义一个类MyArrow
,它是由一些类ArrowHead
和ArrowArc
组成的。
为了说明我的问题,考虑一个简单的玩具例子。让我们定义一个类Room
,它是类wall
、window
和door
的组合。
class Door:
def __init__(self, color='white', height=2.3, width=1.0):
self.color = color
self.height = height
self.width = width
class Window:
def __init__(self, color='white', height=1.0, width=0.8):
self.color = color
self.height = height
self.width = width
class Wall:
def __init__(self, color='white', height=2.5, width=4.0):
self.color = color
self.height = height
self.width = width
class Room:
def __init__(self):
self.door = Door()
self.window = Window()
self.wall = Wall()
Door
、Window
和Wall
的实例变量分别为color
、height
和width
。我希望Room
具有实例变量doorcolor
、windowcolor
、wallcolor
、doorheight
、windowheight
等。我可以将所有九个实例变量显式添加到Room
中,并为它们定义set
和get
函数。但是,如果我后来决定向Door
、Window
或Wall
添加更多实例变量,我也总是需要再次编辑Room
的代码。有没有一种方法可以对Room
进行编码,使其自动采用(并重命名)组件类中的实例变量?
您正在使用组合-无需为您的成员复制访问者。您可以通过您的组合成员轻松访问属性:
r = Room()
print( r.window.color ) # to print the windows color only
您可能会从"零件"的基类和Room
类的更改__init__(..)
中获利:
class Thing:
"""Base class handling init including a name and __str__ and __repr__."""
def __init__(self, name, color, height, width):
self.name = name
self.color = color
self.height = height
self.width = width
def __str__(self):
return repr(self)
def __repr__(self):
return str([self.name, self.color, self.height, self.width])
class Door(Thing):
def __init__(self, color='white', height=2.3, width=1.0):
super(self.__class__, self).__init__(self.__class__.__name__, color, height, width)
class Window(Thing):
def __init__(self, color='white', height=2.3, width=1.0):
super(self.__class__, self).__init__(self.__class__.__name__, color, height, width)
class Wall(Thing):
def __init__(self, color='white', height=2.5, width=4.0):
super(self.__class__, self).__init__(self.__class__.__name__, color, height, width)
class Room:
def __init__(self,*, door=None, window=None, wall=None): # named params only
self.door = door or Door() # default to booring Door if none provided
self.window = window or Window() # same for Window
self.wall = wall or Wall() # same for Wall
def __str__(self):
return str([self.door,self.window,self.wall])
创建对象并打印:
r = Room()
r2 = Room(window=Window("yellow"))
print(r)
print(r2)
r3 = Room( window=Window("green",0.5,0.5), door=Door("black",5,5),
wall=Wall("unicorncolored",5,5) )
print(r3)
输出:
# r - the cheap Room - using default-ing Things
[['Door', 'white', 2.3, 1.0], ['Window', 'white', 2.3, 1.0], ['Wall', 'white', 2.5, 4.0]]
# r2 - with a custom yellow Window
[['Door', 'white', 2.3, 1.0], ['Window', 'yellow', 2.3, 1.0], ['Wall', 'white', 2.5, 4.0]]
# r3 - all custom -
[['Door', 'black', 5, 5], ['Window', 'green', 0.5, 0.5], ['Wall', 'unicorncolored', 5, 5]]