管理(和重命名)类组成的实例变量 [英] Managing (and renaming) instance variables of class compositions

查看:47
本文介绍了管理(和重命名)类组成的实例变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想进行类组合,以使组成类的实例变量成为组合的实例变量,但名称经过调整。

I would like to make a class composition so that the instance variables of the composing classes become instance variables of the composition but with adjusted names.

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

The application for this is in defining new objects for drawing in matplotlib. One example is that I would like to have a function drawMyArrow that draws an arrow with possibly different colors (and other specifications) for its head, tail, and arc. I would like to be able to pass various specifications for the head, tail, and arc via keyword arguments in drawMyArrow. I haven't worked with classes before, but reading up on this online, I believe that the best way to solve my problem is to define a class MyArrow that is a composition of some classes ArrowHead and ArrowArc.

问题,请考虑一个简单的玩具示例。让我们定义一个类 Room ,它是由 wall window

To illustrate my problem, consider a simple toy example. Let's define a class Room that is a composition of the classes wall, window, and 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()

Window Wall 的实例变量code>是颜色高度宽度。我希望 Room 具有实例变量 doorcolor windowcolor 壁彩门高 windowheight 等。我可以将所有九个实例变量明确添加到 Room 并定义 set get 为他们提供的功能。但是,如果我以后决定将更多实例变量添加到 Door Window Wall 我也总是需要再次编辑 Room 的代码。有没有办法编写 Room 的代码,以便它自动采用(并重命名)其组件类中的实例变量?

The instance variables of Door, Window, and Wall are color, height, width. I would like Room to have instance variables doorcolor, windowcolor, wallcolor, doorheight, windowheight, etc. I could add all nine instance variables to Room explicitly and define set and get functions for them. But if I later decide to add more instance variables to Door, Window, or Wall I would always need to edit the code for Room again too. Is there a way to code Room so that it adopts (and renames) the instance variables from its component classes automatically?

推荐答案

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

You are using composition - no need to replicate accessors for your members. You can easily access the attributes through your composed members:

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






您可能会从零件的基类中受益,并为房间的 __ init __(..)获利类:


You might profit from a base class for your "parts" and a changed __init__(..) for your Room class though:

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

这篇关于管理(和重命名)类组成的实例变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆