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