4

我有一个类(dicts 列表),我希望它自行排序:

class Table(list):
…
  def sort (self, in_col_name):
    self = Table(sorted(self, key=lambda x: x[in_col_name]))

但它根本不起作用。为什么?如何避免?除了在外部对其进行排序,例如:

new_table = Table(sorted(old_table, key=lambda x: x['col_name'])

难道不能操纵对象本身吗?更有意义的是:

class Table(list):
  pass

比:

class Table(object):
  l = []
  …
  def sort (self, in_col_name):
    self.l = sorted(self.l, key=lambda x: x[in_col_name])

我认为这很有效。一般来说,在 Python 中没有任何方法可以让对象能够改变自身(不仅仅是实例变量)吗?

4

3 回答 3

17

You can't re-assign to self from within a method and expect it to change external references to the object.

self is just an argument that is passed to your function. It's a name that points to the instance the method was called on. "Assigning to self" is equivalent to:

def fn(a):
   a = 2
a = 1
fn(a)
# a is still equal to 1

分配到self更改self 名称指向的内容(从一个Table实例到这里的新Table实例)。但就是这样。它只是更改名称(在您的方法范围内),并且不会影响底层对象,也不影响指向它的其他名称(引用)。


只需使用以下命令进行排序list.sort

def sort(self, in_col_name):
    super(Table, self).sort(key=lambda x: x[in_col_name])
于 2013-09-03T19:52:32.963 回答
2

Python 总是按值传递。这意味着分配给参数永远不会对函数外部产生影响。self只是您为参数之一选择的名称。

于 2013-09-04T02:52:14.870 回答
0

我对这个问题很感兴趣,因为我从来没有想过这个问题。我查找了list.sort代码,看看它是如何在那里完成的,但显然它在 C 中。我想我明白你的意思了;如果没有super方法可以调用怎么办?然后你可以做这样的事情:

class Table(list):
    def pop_n(self, n):
        for _ in range(n):
            self.pop()

>>> a = Table(range(10))
>>> a.pop_n(3)
>>> print a
[0, 1, 2, 3, 4, 5, 6]

您可以调用self的方法,对其进行索引分配self以及在其类中实现的任何其他内容(或您自己实现的)。

于 2013-09-03T21:44:54.443 回答