代码之家  ›  专栏  ›  技术社区  ›  Colin

在初始化中构造对象__

  •  2
  • Colin  · 技术社区  · 14 年前

    我见过这样的代码:

    class MyClass:
        def __init__(self, someargs):
            myObj = OtherClass()
            myDict = {}
            ...code to setup myObj, myDict...
            self.myObj = myObj
            self.myDict = myDict
    

    当我看到这个的时候,我的第一个想法是:为什么不直接用它呢自我.myObj以及自我.myDict一开始?构造局部对象,然后将它们分配给成员,似乎效率低下。构造对象的代码可能会抛出异常,也许他们这样做是为了不留下半构造的对象?您是这样做的,还是直接构造成员?

    5 回复  |  直到 14 年前
        1
  •  8
  •   aaronasterling    14 年前

    速度更快 构造对象然后将其附加到 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__)
    

    取消:

    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
    

    你看得出来 STORE_ATTR 存储属性 一开始还是会接到电话,但现在 LOAD_ATTR 每次访问字典都会被调用。任务越多,费用就越高。其他指令都是一样的。这仍然是一个可笑的小成本。

    可以利用这个技巧使具有许多迭代的循环运行得更快。像这样的事情并不少见

    foo = self.foo
    factorial = math.factorial
    for x in really_big_iterator:
        foo(factorial(x))
    

    def fast(iterators, sum=sum):
        for i in iterator:
            yield sum(i)
    

        2
  •  3
  •   Marco Mariani    14 年前

    做你更容易理解的事。在这种情况下,这取决于init方法的使用时间。

        3
  •  1
  •   easel    14 年前

    我不确定我是否完全理解你的问题,但请记住: self.myObj = myObj self 很多次了。

        4
  •  0
  •   Wai Yip Tung    14 年前

    两种方法都没有明显的区别。创建局部变量的一个原因是,如果要经常使用init中的变量,则不必重复 self. 这么多。例如

    def __init__(self, someargs):
        self.myObj = OtherClass()
        self.myDict = {}
        self.myDict[1] = self.myObj
        self.myDict[2] = self.myObj
        self.myDict[3] = self.myObj
        self.myDict[4] = self.myObj
        self.myObj = myObj
        self.myDict = myDict
    

    v、 s。

    def __init__(self, someargs):
        obj = OtherClass()
        d = {}
        d[1] = obj
        d[2] = obj
        d[3] = obj
        d[4] = obj
        self.myObj = obj
        self.myDict = d
    

    除非你有充分的理由,否则我不会太担心你的表现。

        5
  •  0
  •   Martijn Pieters    12 年前

    分配一个引用并不需要太多时间,但是每次键入“self”确实需要花费时间。