【问题标题】:How can I create an object that contains instances of a class in Python?如何在 Python 中创建一个包含类实例的对象?
【发布时间】:2025-12-22 05:55:16
【问题描述】:

我想创建一个包含一些类实例的对象。该对象应该是实例的某种列表泛化。例如。我有以下课程:

class car:
    def __init__(self, prize, color)
        self.prize = prize
        self.color = color

现在我想要一个对象cars,它包含许多汽车类实例,但我可以像汽车实例一样使用它,即cars.prize 应该返回我收集的所有实例的奖品列表在那个对象cars

【问题讨论】:

  • def car():?不是class car:?
  • 你试过实现这样的集合吗?发生了什么?
  • 我不知道如何实现这个
  • 您是否考虑过创建一个cars 列表?然后您遍历列表或使用对特定元素的直接访问。用法看起来更接近现实世界。尽管您无法通过cars.prices 获得所有价格而无需额外工作。
  • 这不是一个真正的问题。请注意,SO 既不是代码编写也不是教程服务。如果您想知道如何实现容器,请查看例如docs.python.org/3/reference/….

标签: python class object instance


【解决方案1】:

这个答案的灵感来自于 Sam 使用装饰器的绝妙想法。所以,如果你认为你对这段代码很满意,请给他点。

def singleton(all_cars):
    instances = {} # cars instances
    def get_instance():
        if all_cars not in instances:
            # all_cars is created once
            instances[all_cars] = all_cars()
        return instances[all_cars]
    return get_instance

@singleton
class all_cars:
    def __init__(self):
        self.inventory = {}

    @property
    def prizes(self):
        return [e.prize for e in self.inventory.values()]
    @property
    def colors(self):
        return [e.color for e in self.inventory.values()]        

class car:
    def __init__(self, prize, color):
        self.prize = prize
        self.color = color

    def register(self):
        # Like class all_cars is a singleton it is instantiate once, reason why dict is saved
        cars = all_cars()
        cars.inventory[len(cars.inventory)] = self


if __name__ == '__main__':
    # Creating cars items
    car1 = car("50", "Blue")
    car2 = car("300", "Red")
    car3 = car("150", "Gray")
    # Register part for cars
    car1.register()
    car2.register()
    car3.register()
    # Like class all_cars is a singleton it is instantiate once, reason why dict is saved
    cars = all_cars()

    print(cars.inventory)
    """{0: <__main__.car object at 0x7f3dbc469400>, ---> This is object car1
    1: <__main__.car object at 0x7f3dbc469518>,  ---> This is object car2
    2: <__main__.car object at 0x7f3dbc469550>}  ---> This is object car3"""
    print(cars.prizes)
    """['50', '300', '150']"""
    print(cars.colors)
    """['Blue', 'Red', 'Gray']"""

【讨论】:

  • 这是继承... OP不是那个意思
  • 在这种情况下这并没有什么意义,汽车列表不是汽车,尽管它可能共享一些相同的界面
  • 我完全根据 Sam 的想法审查了设计 :-)
【解决方案2】:

代码中的小错误:您需要在 __init__ 方法定义行的末尾添加一个 :
def __init__(self, prize, color):

这是cars 的实现,它可以满足您的需求。 @property 装饰器的使用允许您将方法作为对象属性访问:

class car:
    def __init__(self, prize, color):
        self.prize = prize
        self.color = color

class cars:
    def __init__(self, list_of_cars):
        for one_car in list_of_cars:
            assert isinstance(one_car, car) # ensure you are only given cars
        self.my_cars = list_of_cars

    @property
    def prize(self):
        return [one_car.prize for one_car in self.my_cars]

    @property
    def color(self):
        return [one_car.color for one_car in self.my_cars]


>>> a = car('prize1', 'red')
>>> b = car('prize2', 'green')
>>> c = car('prize3', 'azure')
>>> carz = cars([a,b,c])
>>> carz.prize
['prize1', 'prize2', 'prize3']
>>> carz.color
['red', 'green', 'azure']

如果需要,您可以对每个对象中的输入添加更多检查,但这是基本框架。希望它有所帮助,快乐编码!

【讨论】:

  • 所以我猜想新类cars不可能继承类car的这些属性作为列表的函数?
  • 并非如此 - 它会从 car 继承单个奖品和单个颜色的初始化,但这并不能达到我们想要的效果。就目前而言,cars 是一个非常薄的汽车列表,可能只有在你想添加更多功能时才真正有用(总结汽车的成本,找到最受欢迎的颜色等)
【解决方案3】:

您可以创建一个新的class car_list(),其中包含汽车列表(您可以对其进行附加、删除等操作)。在该类中,添加一个get_prizes() 方法,该方法通过遍历列表返回奖品列表。例如:

class car_list():
   def __init__(self, cars):
      self.cars = cars # This is a list

   def get_prizes(self):
      return [car.prize for car in self.cars]

【讨论】:

    【解决方案4】:

    我认为你可以这样做:

    class Cars:
        def __init__(self, list_of_cars):
            self.cars_list = list_of_cars
            self.prize = [car.prize for car in self.cars_list]
            self.color = [car.color for car in self.cars_list]
    

    让我们看看它是如何使用的:

    list_of_cars = [Car(1000, "red"), Car(2000, "blue"), Car(3000, "Green")]
    x = Cars(list_of_cars)
    
    print(x.prize)
    # [1000, 2000, 3000]
    
    print(x.color)
    #["red", "blue", "Green"]
    

    【讨论】:

    • 这意味着prizecolor 可能与cars_list 不同步,我会查看属性甚至__getattr__ 以将属性访问重定向到列表跨度>
    • 它怎么会不同步??可以举个例子吗?
    • x.cars_list.append(Car(4000, "Purple"))?
    • 那是name mangled,但可以。
    • 我真的很喜欢这次讨论。最后一个链接信息量很大。我知道那是在浪费你的时间。但对我来说绝对不一样。谢谢:)