在对象的所有实例上调用方法

时间:2015-05-21 21:44:18

标签: python python-3.x

class vehicles:
    class car:
        def drive():
            pass

car1 = car()
car2 = car()
car3 = car()

有没有办法可以在一次通话中调用所有车辆上的驱动功能,而无需明确命名。

3 个答案:

答案 0 :(得分:5)

如果你真的想要它,你必须将它设计到你的模型中 - 例如,你有一个所有创建汽车的注册表。

这不是一件难事 - 我认为最明显的方法是自定义 您的类中的__new__方法保留该注册表并进行调用:

class Base:
    def __new__(cls, *args, **kw):
        self = super.__new__(*args, **kw)
        if not hasattr(cls, _instances):
            cls._instances = []
        cls._instances.append(self)
        return self

    @classmethod
    def call_all(cls, method_name, *args, **kw):
        results = []
        for instance in cls._instances:
            results.append(getattr(instance, method_name)(*args, **kw))
        return results

    def __del__(self):
        self.__class__._instances.remoce(self)

class vehicles:
    class car(Base):

        def drive():
            pass

car1 = car()
car2 = car()
car3 = car()

car.call_all("drive")

另一种方式,因为这是应该保留的类级别的东西 在创建类时,可以在元类中处理。 好处:它将是“纯粹的”,并且当您实例化上述类的第一个对象时,您将不会遇到特殊处理。 坏事:具有不同元类的类很难结合 - 而且 如果你有一个类层次结构,其中某些类需要这种行为,而有些类则不需要 - 在类级别执行此操作可使所有内容保持可互换。

实际上,请注意,创建超类Base是一个可选步骤。如果你只是在你所有项目中的一个地方使用它,逻辑很可能在car类本身内部(正如Narcise的回答,吼叫。)

如果您不想这样做,可以使用垃圾收集器(gc)模块找出对象的所有实例并在其上调用方法。我不认为那会是一件冰,因为gc本身就是一个 cPython的实现细节。

import gc

...
for obj in gc.get_referrers(car):
     if not isinstance(obj, car): continue
     obj.drive()

或在一个丑陋的oneliner:

[getattr(obj, "drive")() for obj in gc.get_referrers(car) if isinstance(obj, car)]

答案 1 :(得分:3)

class Vehicule():

      pos, child = 0, []

      def __init__(self):
          self.__class__.child.append(self)
          self.pos = self.__class__.pos
          self.__class__.pos +=1

      def cond(self):
          print self.pos

      @classmethod
      def drive(cls):
          for v in cls.child:
              v.cond()

测试:

t = Vehicule()
c = Vehicule()
g = Vehicule()
Vehicule.drive()

>>0
>>1
>>2

答案 2 :(得分:1)

要回答你的问题,是的,有办法。您可以使用class variable来跟踪实例。

class vehicles:

    working_vehicles = [] # this is a class variable

    class car:
        def __init__(self):
            vehicles.working_vehicles.append(self) # adds itself to working_vehicles

        def drive(self):
            pass

然后,您可以创建实例,并从vehicles.working_vehicles访问它们。

<强>演示:

首先制作汽车:

>>> car1 = vehicles.car()
>>> car2 = vehicles.car()
>>> car3 = vehicles.car()

然后从vehicles.working_vehicles访问它们。

>>> print(vehicles.working_vehicles)
[<__main__.vehicles.car object at 0x022DF6F0>, <__main__.vehicles.car object at 0x01E97ED0>, <__main__.vehicles.car object at 0x01EAA6B0>]

这在视觉上并没有什么帮助,但您可以在所有汽车上调用drive方法,如下所示:

>>> for car in vehicles.working_vehicles:
...     car.drive()

或者在一行中:

>>> map(lambda car: car.drive(), vehicles.working_vehicles)

哪个不会立即开车。您需要在list迭代器上调用map