Col*_*lin 2 python constructor
我见过看起来像这样的代码:
class MyClass:
def __init__(self, someargs):
myObj = OtherClass()
myDict = {}
...code to setup myObj, myDict...
self.myObj = myObj
self.myDict = myDict
Run Code Online (Sandbox Code Playgroud)
当我看到这个时,我的第一个想法是:为什么不在开始时使用self.myObj和self.myDict?构造本地对象似乎效率低下,然后将它们分配给成员.构造对象的代码可能会抛出异常,也许他们这样做了所以它不会留下一个半构造的对象?你这样做,还是直接构建成员?
构造对象然后将其附加到更快,更可读self.
class Test1(object):
def __init__(self):
d = {}
d['a'] = 1
d['b'] = 2
d['c'] = 3
self.d = d
class Test2(object):
def __init__(self):
self.d = {}
self.d['a'] = 1
self.d['b'] = 2
self.d['c'] = 3
import dis
print "Test1.__init__"
dis.dis(Test1.__init__)
print "Test2.__init__"
dis.dis(Test2.__init__)
Run Code Online (Sandbox Code Playgroud)
反汇编:
Test1.__init__
4 0 BUILD_MAP 0
3 STORE_FAST 1 (d)
5 6 LOAD_CONST 1 (1)
9 LOAD_FAST 1 (d)
12 LOAD_CONST 2 ('a')
15 STORE_SUBSCR
6 16 LOAD_CONST 3 (2)
19 LOAD_FAST 1 (d)
22 LOAD_CONST 4 ('b')
25 STORE_SUBSCR
7 26 LOAD_CONST 5 (3)
29 LOAD_FAST 1 (d)
32 LOAD_CONST 6 ('c')
35 STORE_SUBSCR
8 36 LOAD_FAST 1 (d)
39 LOAD_FAST 0 (self)
42 STORE_ATTR 0 (d)
45 LOAD_CONST 0 (None)
48 RETURN_VALUE
Test2.__init__
12 0 BUILD_MAP 0
3 LOAD_FAST 0 (self)
6 STORE_ATTR 0 (d)
13 9 LOAD_CONST 1 (1)
12 LOAD_FAST 0 (self)
15 LOAD_ATTR 0 (d)
18 LOAD_CONST 2 ('a')
21 STORE_SUBSCR
14 22 LOAD_CONST 3 (2)
25 LOAD_FAST 0 (self)
28 LOAD_ATTR 0 (d)
31 LOAD_CONST 4 ('b')
34 STORE_SUBSCR
15 35 LOAD_CONST 5 (3)
38 LOAD_FAST 0 (self)
41 LOAD_ATTR 0 (d)
44 LOAD_CONST 6 ('c')
47 STORE_SUBSCR
48 LOAD_CONST 0 (None)
51 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
你可以看到,STORE_ATTR只有在最后一次做到这一点时才会被调用.从另一个方面来说,STORE_ATTR仍然会在开始LOAD_ATTR时调用,但现在每次访问字典时都会调用它.分配越多,成本越高.其他每条指令都是一样的.它仍然是一个可笑的小成本.
这个技巧可以被利用来使循环具有更多的迭代运行更快.看到类似的事情并不罕见
foo = self.foo
factorial = math.factorial
for x in really_big_iterator:
foo(factorial(x))
Run Code Online (Sandbox Code Playgroud)
另一个技巧是将全局函数作为默认参数传递给具有类似循环的函数,或者调用整个集合以保存一些属性查找:它位于本地范围内,这是第一个查看的范围.
def fast(iterators, sum=sum):
for i in iterator:
yield sum(i)
Run Code Online (Sandbox Code Playgroud)
现在总和是在当地范围内.