2014-10-11 50 views
2

我正在寻找一种将函数应用于类的所有实例的方法。举个例子:将函数应用于类的所有实例

class my_class: 

    def __init__(self, number): 
     self.my_value = number 
     self.double = number * 2 

    @staticmethod 
    def crunch_all(): 
     # pseudocode starts here 
     for instances in my_class: 
      instance.new_value = instance.my_value + 1 

所以命令my_class.crunch_all()应该添加一个新的属性new_value所有现有实例。我猜我必须使用@staticmethod才能使其成为“全球”功能。

我知道我可以继续正在通过my_class.instances__init__添加类似my_class.instances.append(number)然后循环定义的情况下的轨道,但我至今没有运气用,要么。此外,我想知道是否有更通用的存在。这甚至有可能吗?

+3

它应该是'@ classmethod',而不是'@ staticmethod'。是的,你必须跟踪类属性中的所有类的实例。 – jonrsharpe 2014-10-11 14:17:54

回答

5

注册对象与在初始化类(即__init__)和限定一个类方法(即@classmethod)为类:

class Foo(object): 
    objs = [] # registrar 

    def __init__(self, num): 
     # register the new object with the class 
     Foo.objs.append(self) 
     self.my_value = num 

    @classmethod 
    def crunch_all(cls): 
     for obj in cls.objs: 
      obj.new_value = obj.my_value + 1 

例如:

>>> a, b = Foo(5), Foo(7) 
>>> Foo.crunch_all() 
>>> a.new_value 
6 
>>> b.new_value 
8 
+0

另外需要注意的是,在Python中,这个类变量可以被所有实例访问。你可以看到'id(Foo.objs)','id(a.objs)'和'id(b.objs)'都指向同一个东西。所以如果有人想要,他们可以做一些令人讨厌的事情,比如'a.objs.append(“hello”)'现在'crunch_all'将会出错,因为'objs'结尾的字符串没有'my_value '属性来访问。 – ely 2014-10-11 14:33:39

+0

由于这种情况发生在'objs'内容发生变异时(当它完全重新分配时,'__setattr__'序列只发生在'a'和其他人之间),所以你可以简单地通过使'objs'成为一个'元组'它不能被突变,然后在构造函数中,从旧的内容中创建一个新的“元组”,并添加正在创建的实例。 – ely 2014-10-11 14:37:19

+0

这是一个有用的相关问题:。 – ely 2014-10-11 14:40:33