Python 对对象的所有实例调用方法

Python 对对象的所有实例调用方法,python,python-3.x,Python,Python 3.x,是否有一种方法可以在一次调用中调用所有汽车的驱动功能,而不必明确地命名每辆汽车。如果您真的需要,您必须将其设计到您的模型中-例如,您拥有所有已创建汽车的注册表 这不是一件困难的事情——我认为最明显的方法是定制 \uuuuu new\uuuuu方法来保留该注册表,并进行调用: class vehicles: class car: def drive(): pass car1 = car() car2 = car() car3 = car() 另一

是否有一种方法可以在一次调用中调用所有汽车的驱动功能,而不必明确地命名每辆汽车。

如果您真的需要,您必须将其设计到您的模型中-例如,您拥有所有已创建汽车的注册表

这不是一件困难的事情——我认为最明显的方法是定制
\uuuuu new\uuuuu
方法来保留该注册表,并进行调用:

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

car1 = car()
car2 = car()
car3 = car()
另一种方式,因为这是类级别的东西,应该保留 创建类时,可以在元类中处理。 好处:它将是“纯”的,当您像上面那样实例化该类的第一个对象时,您不会有特殊的处理。 坏处:具有不同元类的类很难组合,而且 如果您有一个类层次结构,其中一些类需要这种行为,而一些不在类级别这样做可以保持所有内容的可互换性

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

如果不想这样做,可以使用垃圾收集器(
gc
)模块找出对象的所有实例,并对它们调用方法。我不认为这是ice的事情,因为
gc
本身就是一个 cPython的实现细节

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")
或者用丑陋的一行:

import gc

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

要回答你的问题,是的,有一种方法。您可以使用来跟踪实例

[getattr(obj, "drive")() for obj in gc.get_referrers(car) if isinstance(obj, car)]
然后,您可以创建实例,并从
vehicles.working\u vehicles
访问它们

>>> car1 = vehicles.car()
>>> car2 = vehicles.car()
>>> car3 = vehicles.car()
演示:

首先创建汽车:

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
然后从
车辆访问它们。工作车辆

>>> car1 = vehicles.car()
>>> car2 = vehicles.car()
>>> car3 = vehicles.car()
或者在一行中:

>>> for car in vehicles.working_vehicles:
...     car.drive()
这不会立即驱动汽车。您需要在
map
迭代器上调用
list

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

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

为什么要自定义
\uuuu new\uuuuu
而不是
\uuuu init\uuuuu
?我想这可以通过
\uuuuu init\uuuuuuu
来完成-但由于这只会处理类属性,而派生的类可能希望使用
\uuuuu init\uuuuuuu
来实现其他目的,我认为它得到了更好的分离。这更多的是一种感觉,而不是“你应该这么做”。为什么要创建一个基类,而
vehicles
类看起来似乎是用来存放车辆类型的?创建基类是完全可选的——我应该在本文中提到这一点——但它是一种机制,适用于任何继承自它的类,我怀疑“car”将是唯一的地方。你必须一次完成所有任务,你是说并行吗?还是一个接一个?发布的代码有语法错误
car1=vehicles.car()
将调用构造函数。drive还需要一个
self
parameternice,简单回答-您可以使用“@classmethod”而不是“staticmethod”,使用cls.child而不是vehicleule.child-这将使它也可以与子类一起工作,注意,Python 3中的
map
返回的迭代器不会立即驱动汽车,而Python 2中的
list
会立即驱动汽车。
t = Vehicule()
c = Vehicule()
g = Vehicule()
Vehicule.drive()

>>0
>>1
>>2