class vehicles:
class car:
def drive():
pass
car1 = car()
car2 = car()
car3 = car()
有没有办法可以在一次通话中调用所有车辆上的驱动功能,而无需明确命名。
答案 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
。