【问题标题】:Python Class. key exists as self.key, but doesn't exists in self.__dict__Python 类。 key 作为 self.key 存在,但在 self.__dict__ 中不存在
【发布时间】:2014-10-04 13:58:25
【问题描述】:

我的班级包含三个大字典,一个出现在self.__dict__,另外两个没有。

例子:

class MyClass:
  big_matrix = {}
  side_array = {}
  map_of_data = {}
  def __init__( self ):
      # etc...

当我试图将self.__dict__ 转储到终端时,我成功地只看到了big_matrix 而没有看到其他字典。

__init__ 中没有声明一个数组,稍后在其他函数中声明。

请帮帮我?

【问题讨论】:

  • 你能告诉我们__init__吗?这将决定 instance 变量,而不是您在此处声明的 class 变量。
  • __init__中没有声明一个数组,稍后在其他函数中声明。
  • 你有没有在 init 方法中初始化它们? self.__dict 中应该没有类属性
  • MyClass.__dict__ 将列出所有这些,但 MyClass 的实例不会

标签: python arrays class oop


【解决方案1】:

您应该在__init__ 中初始化变量并将它们分配给对象self,以使它们属于实例命名空间(在对象上调用__dict__ 时显示的命名空间。

否则,它们不是您的 object instance 命名空间的一部分,而是 class 命名空间的一部分。

您可能会在实例命名空间中看到big_matrix,因为您正在类的其他位置创建self.big_matrix


实例命名空间中的变量

class MyClass:
    def __init__( self ):
        self.big_matrix = {}
        self.side_array = {}
        self.map_of_data = {}

变量属于实例命名空间:

>>> print MyClass().__dict__ 
{'big_matrix': {}, 'side_array': {}, 'map_of_data': {}}

该类在其命名空间中没有任何变量

>>> print MyClass.__dict__
{}

类命名空间中的变量

class MyClass:
    big_matrix = {}
    side_array = {}
    map_of_data = {}

实例在其命名空间中没有任何变量

>>> print MyClass().__dict__ 
{}

所有变量都属于 class 命名空间(加上该类使用的其他变量):

>>> print MyClass.__dict__
{'big_matrix': {}, 'side_array': {}, '__module__': '__main__', 'map_of_data': {}, '__doc__': None}

【讨论】:

  • 你说得对,大矩阵的初始化方式不同于其他两个数组。什么是正确的,在__init__ 或 Class vars 中声明这些变量?变量定义不正确是python特有的错误吗?
  • 如果您的矩阵与实例相关,则将它们定义为实例变量。如果它们是静态类(任何对象都会共享它们),则将它们声明为类变量。
【解决方案2】:

class attributesinstance attributes 之间的区别最好用一个例子来说明:

In [25]: class MyClass:
   ....:       cls_dict = {} # class attribute
   ....:       def __init__( self ):
   ....:               pass
   ....:           

In [26]: 

In [26]: m = MyClass() # first instance

In [27]: m.cls_dict["foo"] = "bar" # first instance adds to dict

In [28]: m1 = MyClass() # second instance 

In [29]: m1.cls_dict["bar"] = "foo" # second instance adds to dict

In [30]: MyClass.cls_dict
Out[30]: {'bar': 'foo', 'foo': 'bar'} # both entries in the dict

In [31]: m.cls_dict  # can be accessed through the class or an instance
Out[31]: {'bar': 'foo', 'foo': 'bar'}
In [32]: m1.cls_dict
Out[32]: {'bar': 'foo', 'foo': 'bar'}

实例属性:

In [33]: class MyClass:
   ....:    def __init__( self ):
   ....:       self.ins_dict = {}
   ....:         

In [34]: m = MyClass()

In [35]: m.ins_dict["foo"] = "bar" 

In [36]: m1 = MyClass()

In [37]: m1.ins_dict["bar"] = "foo"

In [38]: m.ins_dict   # each instance has its own `ins_dict`
Out[38]: {'foo': 'bar'}

In [39]: m1.ins_dict
Out[39]: {'bar': 'foo'}

class attributesinstances 之间共享,instance attributes 是为每个实例单独创建的。

每当您更改 class attribute cls_dict 时,这两个实例都会更改。

【讨论】:

  • 共享是什么意思?两个实例是否可以访问第一个示例中的相同 cls_dict = {}
  • 是的。您可以从示例中看到,无论是通过实例还是使用类访问它,对类属性 dict 的任何更新都会将数据添加到同一个 dict。在实例属性dict中,每次创建类的实例时,都会为每个实例创建一个新的dict对象。
  • 不客气。你选择哪一个完全取决于你想用它做什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多