【问题标题】:Python class constructor returns an empty valuePython 类构造函数返回一个空值
【发布时间】:2015-06-30 23:37:54
【问题描述】:

我正在编写一个基于列表的 Python 类。构造函数基于作为参数传递的另外两个列表构建一个列表。逻辑大致是:将列表 A 复制到新实例,然后迭代列表 B,添加一些条目并使用其他条目修改列表 A 中的条目。

我有两个版本的构造函数。首先,列表 A 和列表 B 由循环处理。然后我决定变聪明;我使用了一种理解来替换将列表 A 添加到新实例的循环。

构造函数的第一个版本完美运行。第二个版本返回一个空列表,尽管我可以在构造函数结束之前立即在调试器中查看 self 的值,并且 看到它是正确的。

为什么会发生这种情况,我该怎么做才能使第二个版本正常工作?

这是导致第二个版本行为不端的代码。它将列表 A 复制到新实例,然后遍历该实例以更新表示列表 B 中项目的字典中的数据。 ba 是列表 A; getkey 是一个函数(作为参数传递),它从列表元素派生字典键; _dictb 是一个字典,其中包含列表 B 中每个元素的一个元素。

self = [ [bae,None] for bae in ba ]  # Copy list A to self
for n in xrange(0,len(self)) :       # Iterate over list B
    _key = getkey( self[n][0])
    if _dictb.has_key(_key) :
        _dictb[_key] = n

在第一个有效的版本中,上面的代码被替换为这个;执行的操作和变量的含义是一样的:

for bae in ba :
    _key = getkey(bae)
    if _dictb.has_key(_key) :
        _dictb[_key] = len(self)
    self.append( [bae,None] )

【问题讨论】:

标签: python list class constructor


【解决方案1】:

我假设您在这里真正谈论的是 Python 构造函数,并且出于某种奇怪的原因,省略了类定义和 def __init__ 语句。在您提供的第一个代码 sn-p 的“第二个版本”中,您的第一行将一个列表分配给一个名为“self”的局部变量。这不会用不同的对象替换正在构造的对象。从构造函数返回的是新对象,而不是变量 self。

解决方案:不要分配给自己。曾经。甚至不要考虑它。

您也不能使用列表推导来创建列表的子类,只能创建列表的实例。您的“第一个版本”(第二个代码 sn-p)可以正常工作,并且没有任何问题。

另外:您应该将“_dictb.has_key(key)”替换为“_dictb 中的键”。

【讨论】:

    【解决方案2】:

    如果您对 list 进行子类化,您不想在构造函数中重新分配对象 self。这不会影响列表本身的内部内容,而是将 self 的引用替换为您刚刚创建的新列表理解。

    换句话说,它不会达到你想要的效果。

    改为执行以下操作:

    class MyList(list):
    
        def __init__(self, xs):
            super(MyList, self).__init__()
    
            for x in xs:  # Assign all values of xs to the list object ``self``
                self.append(x)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-11
      • 2012-08-07
      • 2011-10-14
      • 1970-01-01
      • 1970-01-01
      • 2011-11-13
      • 1970-01-01
      • 2022-11-12
      相关资源
      最近更新 更多