Why does assigning to self not work, and how to work around the issue?

前端 未结 3 549
南旧
南旧 2020-12-11 21:04

I have a class (list of dicts) and I want it to sort itself:

class Table(list):
…
  def sort (self, in_col_name):
    self = Table(sorted(self,          


        
相关标签:
3条回答
  • 2020-12-11 21:35

    I was intrigued by this question because I had never thought about this. I looked for the list.sort code, to see how it's done there, but apparently it's in C. I think I see where you're getting at; what if there is no super method to invoke? Then you can do something like this:

    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]
    

    You can call self's methods, do index assignments to self and whatever else is implemented in its class (or that you implement yourself).

    0 讨论(0)
  • 2020-12-11 21:46

    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
    

    Assigning to self changes what the self name points to (from one Table instance to a new Table instance here). But that's it. It just changes the name (in the scope of your method), and does affect not the underlying object, nor other names (references) that point to it.


    Just sort in place using list.sort:

    def sort(self, in_col_name):
        super(Table, self).sort(key=lambda x: x[in_col_name])
    
    0 讨论(0)
  • 2020-12-11 21:54

    Python is pass by value, always. This means that assigning to a parameter will never have an effect on the outside of the function. self is just the name you chose for one of the parameters.

    0 讨论(0)
提交回复
热议问题