管理(和重命名)类组成的实例变量

时间:2019-02-09 22:16:56

标签: python python-3.x class composition

我想制作一个类组合,以便组成类的实例变量成为组合的实例变量,但名称经过调整。

此应用程序是在matplotlib中定义要绘制的新对象。一个示例是我想拥有一个函数drawMyArrow,该函数为其头部,尾部和弧线绘制可能具有不同颜色(和其他规格)的箭头。我希望能够通过drawMyArrow中的关键字参数传递有关头,尾和弧的各种规范。我以前没有使用过类,但是在网上阅读了此书后,我认为解决我的问题的最好方法是定义一个类MyArrow和{ {1}}。

为说明我的问题,请考虑一个简单的玩具示例。让我们定义一个类ArrowHead,该类由类ArrowArcRoomwall组成。

window

doorclass 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的实例变量是WindowWallcolor。我希望height具有实例变量widthRoomdoorcolorwindowcolorwallcolor等,我可以添加所有九个实例明确地doorheight的变量,并为其定义windowheightRoom函数。但是,如果以后我决定向setgetDoor添加更多实例变量,我总是也总是需要再次编辑Window的代码。有没有一种方法可以对Wall进行编码,以便它自动从其组件类中采用(并重命名)实例变量?

1 个答案:

答案 0 :(得分:3)

您正在使用合成-无需为成员复制访问器。您可以轻松地通过组成的成员通过 访问属性:

r = Room()
print( r.window.color ) # to print the windows color only

尽管您可能会从“零件”的基础类中受益,但对于__init__(..)类的Room也可能会受益:

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]]