我不知道是否有访问使用相同类的方法内的类变量(一个字典)时任何性能差异:
self.class_variable_dict.add(some_key, some_value)
和
ClassName.class_variable_dict.add(some_key, some_value)
显然,两者都将只要有与没有同名的实例变量,但有一个我们应该更喜欢一个比其他任何理由/使用的情况下工作吗?
我不知道是否有访问使用相同类的方法内的类变量(一个字典)时任何性能差异:
self.class_variable_dict.add(some_key, some_value)
和
ClassName.class_variable_dict.add(some_key, some_value)
显然,两者都将只要有与没有同名的实例变量,但有一个我们应该更喜欢一个比其他任何理由/使用的情况下工作吗?
通过访问其ClassName
,而不是通过self
会更快稍微的,因为如果你通过访问它self
必须先检查实例命名空间。 但我并不指望的差异是在所有显著,除非你有分析信息表明,它是。
所以我会建议使用哪一个你认为是更容易阅读/理解作为一个人。
语义上,它们将是不同仅当class_variable_dict
变量被某处阴影-特别是,如果(a) self
定义了相同的名称的变量; 或(b) self
为的子类的实例ClassName
,和该子类(或其碱这仍然的一个子类中的一个ClassName
)定义了相同的名称的变量。 如果这些都不是真实的,那么就应该是相同的语义。
编辑:
delnam好点:有因素,可能使任何更快。 我坚持我断言的差异将是微不足道的,除非它是在一个非常非常紧密的循环。 为了测试它,我创造了我能想到的最紧密的循环,并用定时它timeit
。 下面是结果:
基于多次运行,它看起来像误差线约1秒 - 也就是说,这是一个统计上显著差异,但可能不值得担心。 这里是我的测试代码:
import timeit
setup='''
class A:
var = {}
def f1(self):
x = A.var
def f2(self):
x = self.var
a = A()
'''
print 'access via class var: %.3f' % timeit.timeit('a.f1()', setup=setup, number=100000000)
print 'access via inst var: %.3f' % timeit.timeit('a.f2()', setup=setup, number=100000000)
让我们来看看都有哪些不同的选项都这样做。
In [1]: class Foo:
...: bar = {}
...:
In [2]: import dis
In [3]: dis.dis(lambda: Foo.bar.add(1,2))
1 0 LOAD_GLOBAL 0 (Foo)
3 LOAD_ATTR 1 (bar)
6 LOAD_ATTR 2 (add)
9 LOAD_CONST 1 (1)
12 LOAD_CONST 2 (2)
15 CALL_FUNCTION 2
18 RETURN_VALUE
In [4]: dis.dis(lambda: Foo().bar.add(1,2))
1 0 LOAD_GLOBAL 0 (Foo)
3 CALL_FUNCTION 0
6 LOAD_ATTR 1 (bar)
9 LOAD_ATTR 2 (add)
12 LOAD_CONST 1 (1)
15 LOAD_CONST 2 (2)
18 CALL_FUNCTION 2
21 RETURN_VALUE
正如你可以从看,这两种风格从创建在第二种情况下,对象生成相同的字节码放在一边。
其他方面的情况是,它并没有关系。 使用任何表达你的目标在最精确的方式。 只有优化如果速度事项。
我建议你只是去ClassName.dict_value[key] = value
实例变量与Python中的类变量
还看到我发布的基于@Edward洛珀测试包括模块变量以及它们的速度甚至超过类变量更广泛的测试在这里同样的问题。