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

Python 管理(和重命名)类组合的实例变量,python,python-3.x,class,composition,Python,Python 3.x,Class,Composition,我想制作一个类组合,这样组合类的实例变量就可以成为组合的实例变量,但名称要经过调整 此应用程序用于在matplotlib中定义用于绘图的新对象。一个例子是,我希望有一个函数drawMyArrow,它可以为箭头的头部、尾部和圆弧绘制可能不同颜色(和其他规格)的箭头。我希望能够通过drawMyArrow中的关键字参数传递头、尾和弧的各种规格。我以前没有使用过类,但是通过在线阅读,我相信解决我的问题的最好方法是定义一个类MyArrow,它是一些类ArrowHead和arroarroarc的组合 为了说

我想制作一个类组合,这样组合类的实例变量就可以成为组合的实例变量,但名称要经过调整

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

为了说明我的问题,考虑一个简单的玩具例子。让我们定义一个类
房间
,它由类
组成

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()

的实例变量为
颜色
高度
宽度
。我希望
Room
具有实例变量
doorcolor
windowcolor
wallcolor
doorheight
windowheight
,等等。我可以将所有九个实例变量显式地添加到
Room
,并为它们定义
set
get
函数。但是,如果我以后决定向
添加更多实例变量,我将始终需要再次编辑
房间
的代码。是否有一种方法可以对
Room
进行编码,使其自动采用(并重命名)其组件类中的实例变量?

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

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

您可能会从“部件”的基类和
房间
类的更改
\uuuu init\uuuu(…)
中获益,不过:

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

例如,有一些
\uuu getattr\uuuu
魔术,但这会破坏编辑器可能提供的任何自动完成和智能感知。你真的需要这个吗?您不能直接调用成员字段的属性吗?请阅读,谢谢,这非常有用!使用
r.window.color
访问组件属性似乎是一条正确的道路,但它给我带来了新的问题。我把它们寄出去了。