【问题标题】:Python: Use of dict derived class - strange behavior of self={Python:使用 dict 派生类 - self={ 的奇怪行为
【发布时间】:2012-10-21 06:45:20
【问题描述】:

A类和B类有什么区别?

自己怎么了?

为什么要逐行声明self?

class A(dict):
  def __init__(self):
    self={1:"you", 2:"and me"}
    print "inside of class A",self
class B(dict):
  def __init__(self):
    self[1]="you"
    self[2]="and me"
    print "inside of class B",self

a=A()
print "outside of class A",a
b=B()
print "outside of class B",b

结果:

inside of class A {1: 'you', 2: 'and me'}
outside of class A {}
inside of class B {1: 'you', 2: 'and me'}
outside of class B {1: 'you', 2: 'and me'}

【问题讨论】:

    标签: python class dictionary self


    【解决方案1】:
      def __init__(self):
        self={1:"you", 2:"and me"}
    

    这不会修改作为self 传递的对象,而是将局部变量self 重新绑定到新的dict。

    【讨论】:

    • @pst:“参考”有什么问题? Python 中的所有值都是引用
    • @newacct 我遇到的问题是它在编程中是一个重载且有些模糊的术语。因此,我更喜欢尽可能避免使用,特别是当这个答案中不需要时。
    • reference 的一个明显问题是,C++ 多年来一直使用它作为对象引用类型,其中像上面的赋值 携带预期的意思。
    • @newacct 我宁愿说“Python 中的所有变量都是对值的引用”。是的,C++ 引用是不可变的,但其中真正有趣的部分是整个“值类型”。 C++ 是我所知道的唯一一种面向对象语言,其中 A=B; 在对象上下文中的意思是“让对象 A 在值方面变得像 B 一样”,而不是“让变量 A 引用对象 B”。前者在执行 OO 时很少有用,并且自动生成的 operator= 使事情变得更加混乱。
    【解决方案2】:

    正如其他人所说,分配给self 是没有用的,因为它只会更改局部变量的值,而不会影响正在构造的字典。你想要的是这样的:

    self.update({1:"you", 2:"and me"})
    

    甚至:

    dict.__init__(self, {1:"you", 2:"and me"})
    

    如果您真的想控制您的类构造函数返回的哪个实例(例如,实现实例缓存),look up __new__

    【讨论】:

    【解决方案3】:

    在 A 类中,您将分配给本地 self 变量。当__init__ 被调用时,self 包含一个引用,所以构造的对象。您正在将其完全重新分配给其他东西; 这根本不会改变 A 类的实例

    事实上,如果你在类 A 上定义一个新方法,你会注意到你分配给 self 的字典在那里甚至不可见。在__init__ 返回的那一刻,它变得未被引用。

    【讨论】:

      【解决方案4】:

      只是添加其他好的答案。你可以看到字节码的区别:

      A的字节码:

      Disassembly of __init__:
        3           0 BUILD_MAP                2
                    3 LOAD_CONST               1 ('you')
                    6 LOAD_CONST               2 (1)
                    9 STORE_MAP           
                   10 LOAD_CONST               3 ('and me')
                   13 LOAD_CONST               4 (2)
                   16 STORE_MAP           
                   17 STORE_FAST               0 (self)  # stores values in local variable
                                                         # i.e not changing the object at all
      
        4          20 LOAD_CONST               5 ('inside of class A')
                   23 PRINT_ITEM          
                   24 LOAD_FAST                0 (self)
                   27 PRINT_ITEM          
                   28 PRINT_NEWLINE       
                   29 LOAD_CONST               0 (None)
                   32 RETURN_VALUE        
      
      None
      

      B的字节码:

      Disassembly of __init__:
        8           0 LOAD_CONST               1 ('you')
                    3 LOAD_FAST                0 (self)  #loads self, i.e instance of dict
                    6 LOAD_CONST               2 (1)
                    9 STORE_SUBSCR                       #store value in it   
      
        9          10 LOAD_CONST               3 ('and me')
                   13 LOAD_FAST                0 (self)
                   16 LOAD_CONST               4 (2)
                   19 STORE_SUBSCR        
      
       10          20 LOAD_CONST               5 ('inside of class B')
                   23 PRINT_ITEM          
                   24 LOAD_FAST                0 (self)
                   27 PRINT_ITEM          
                   28 PRINT_NEWLINE       
                   29 LOAD_CONST               0 (None)
                   32 RETURN_VALUE        
      
      None
      

      【讨论】:

        猜你喜欢
        • 2019-12-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多