类变量查找与实例变量查找

时间:2012-10-16 13:21:52

标签: python instance-variables class-variables

我有一个包含许多类变量的类:

c_dict1c_dict2c_dict3

它们都是字典,并使用下面的一些实例变量存储一些值作为键。

我有这个类的几百个实例,每个实例都有以下实例变量

i_key1i_key2i_key3i_attr1i_attr2i_attr3

他们前三个(i_key*)可用于在类变量中查找后三个(i_attr*)。换句话说:

self.i_attr1 = MyClass.c_dict1(i_key1)
self.i_attr2 = MyClass.c_dict2(i_key2)
self.i_attr3 = MyClass.c_dict3(i_key3)

我的问题是:

在性能方面,我应该在本地维护实例变量i_attr*,还是应该使用类变量c_dict*通过字典查找来访问它们?显然,通过类变量做的每个实例都可以删除三个指针,这可能会节省一些内存,但是这样做有什么明显的速度惩罚吗?

2 个答案:

答案 0 :(得分:4)

  

在性能方面,我应该在本地维护实例变量i_attr *,还是应该使用类变量c_dict *通过字典查找来访问它们?

如果这种恒定时间微优化很重要而且不成熟,可能不要使用python。

我强烈怀疑这是过早的优化,你还没有把它确定为火锅,因为如果你有,你可以两种方式分析你的代码,并且不会在这里问。

你可以通过担心你的架构获得更多的加速,你是否应该运行一个可以利用PyPi等的长期过程。

答案 1 :(得分:0)

在性能方面,您的问题没有一般性答案,因为它取决于访问频率以及您如何使用结果,您只需要尝试查看。使用timeitprofile运行代码以查看结果。

如果您希望c_dictNi_attrN保持同步,最好使用以下内容:

self.i_attrN = property(lambda self:       MyClass.c_dictN[i_keyN], 
                        lambda self, val:  MyClass.c_dictN[i_keyN] = val)

(请注意,您也可以使用setattrgetattr设置循环中的所有字段(如果它们的名称与您的示例相同)。

如果您可以执行上述操作,并且可以更改类的合同,则另一种解决方案是使用索引访问器,例如:

def __getitem__(self, idx):
    return MyClass.c_dict[idx][self.i_key[idx]]

def __setitem__(self, idx, val):
    MyClass.c_dict[idx][self.i_key[idx]] = val

然后您可以从

更改访问权限
a = myobj.i_attrN
myobj.i_attrN = b

a = myobj[N]
myobj[N] = b