Метод Python, изменяющий значение self (дикто-унаследованный класс) [duplicate]

В отличие от других языков, имеющих переменную и значение, у Python есть имя и объект.

Этот оператор:

a = [1,2,3]

означает присвоение списку (объекту) имени a, и это:

b = a

просто дает тому же объекту a новое имя b, поэтому всякий раз, когда вы что-то делаете с a, объект изменяется, и поэтому b изменяется .

Единственный способ сделать действительно копию a для создания нового объекта, как и другие ответы, уже сказал.

Вы можете увидеть больше об этом здесь .

4
задан Thomas Orozco 29 August 2014 в 10:52
поделиться

3 ответа

Я был заинтригован этим вопросом, потому что я никогда не думал об этом. Я искал код 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 и все, что еще реализовано в своем классе (или что вы реализовать себя ).

0
ответ дан Community 21 August 2018 в 11:32
поделиться

Python всегда проходит по значению. Это означает, что назначение параметра никогда не будет влиять на внешнюю сторону функции. self - это просто имя, которое вы выбрали для одного из параметров.

1
ответ дан newacct 21 August 2018 в 11:32
поделиться
  • 1
    Нет, это не пропуск по значению, все наоборот. Проблема в назначении не делает то, что вы думаете. – Mark Ransom 4 September 2013 в 04:01
  • 2
    @MarkRansom: Вы ошибаетесь. Это пропуск по значению. Вы просто не знаете, что такое пропуск по значению. – newacct 4 September 2013 в 04:10
  • 3
    Это может выглядеть как look как пропуск по значению, но это не так. Если вы выполняете какую-либо мутацию в параметре функции, вы обнаружите, что она также изменяет исходный объект. Назначение не является мутацией, если только это не член или срез объекта. См. ideone.com/vP7m25 – Mark Ransom 4 September 2013 в 04:55
  • 4
    @MarkRansom: он проходит по значению. Мутирование объекта, на которое указывает переменная, не присваивает переменной. Назначение-на-срез не является назначением - он вызывает метод (.__setitem__()) объекта, на который указывает эта переменная. – newacct 4 September 2013 в 08:49
  • 5
    Семантика, которую я часто слышал, заключается в том, что python рассматривается как «вызов по объекту»: effbot.org/zone/call-by-object.htm – qwwqwwq 23 September 2013 в 16:07

Вы не можете повторно назначить self из метода и ожидать, что он изменит внешние ссылки на объект.

self - это просто аргумент, передаваемый вашей функции. Это имя указывает на экземпляр вызова метода. «Назначение self» эквивалентно:

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])
16
ответ дан Thomas Orozco 21 August 2018 в 11:32
поделиться
  • 1
    Хорошая идея, но похоже, что list.sort () не поддерживает ключевой аргумент. (По крайней мере, он сбросил TypeError и в документе Python я не нашел ключевого аргумента) Thx – Gyula Sámuel Karli 3 September 2013 в 20:59
  • 2
    @ GyulaSámuelKarli Упс, мой плохой - нам нужно вызвать оригинальный метод list.sort здесь, используя super. Вместо этого мы вызывали Table.sort, что не поддерживает его, потому что мы его не реализовали. – Thomas Orozco 3 September 2013 в 21:04
  • 3
    @ThomasOrozco: и это также вызовет бесконечную рекурсию ^^ – nneonneo 3 September 2013 в 21:08
  • 4
    @nneonneo Который был бы bad =) (но, возможно, немного легче отлаживать! Я всегда нашел документацию для list.sort довольно сложно найти!;)) – Thomas Orozco 3 September 2013 в 21:09
  • 5
    @ GyulaSámuelKarli Вы можете изменить объект, но вы не можете заменить его. Это связано с тем, что ваш метод не контролирует ссылки, которые существуют для объекта, другие части кода. – Thomas Orozco 3 September 2013 в 21:39
Другие вопросы по тегам:

Похожие вопросы: