Python: & ldquo; __ iadd __ & rdquo; и & ldquo; + = & rdquo; имеют разные эффекты [дубликат]

Вот еще одно решение для получения записей только с полем, которое имеет максимальное значение для этого поля. Это работает для SQL400, на котором я работаю. В этом примере записи с максимальным значением в поле FIELD5 будут получены следующим оператором SQL.

SELECT A.KEYFIELD1, A.KEYFIELD2, A.FIELD3, A.FIELD4, A.FIELD5
  FROM MYFILE A
 WHERE RRN(A) IN
   (SELECT RRN(B) 
      FROM MYFILE B
     WHERE B.KEYFIELD1 = A.KEYFIELD1 AND B.KEYFIELD2 = A.KEYFIELD2
     ORDER BY B.FIELD5 DESC
     FETCH FIRST ROW ONLY)
44
задан smci 23 July 2011 в 02:56
поделиться

4 ответа

Да, переопределите метод __iadd__ . Пример:

def __iadd__(self, other):
    self.number += other.number
    return self    
81
ответ дан Mauro Baraldi 5 September 2018 в 09:04
поделиться

В дополнение к перегрузке __iadd__ (не забудьте вернуть self!), вы также можете отступить на __add__, так как x + = y будет работать как x = x + y. (Это одна из ловушек оператора + =.)

>>> class A(object):
...   def __init__(self, x):
...     self.x = x
...   def __add__(self, other):
...     return A(self.x + other.x)
>>> a = A(42)
>>> b = A(3)
>>> print a.x, b.x
42 3
>>> old_id = id(a)
>>> a += b
>>> print a.x
45
>>> print old_id == id(a)
False

Даже даже опрокидывает экспертов :

class Resource(object):
  class_counter = 0
  def __init__(self):
    self.id = self.class_counter
    self.class_counter += 1

x = Resource()
y = Resource()

Какие значения делают вы ожидаете x.id, y.id и Resource.class_counter?

12
ответ дан Community 5 September 2018 в 09:04
поделиться

В дополнение к тому, что правильно указано в ответах выше, стоит явно уточнить, что когда __iadd__ переопределяется, операция x += y НЕ заканчивается окончанием метода __iadd__.

Вместо этого он заканчивается на x = x.__iadd__(y). Другими словами, Python присваивает возвращаемое значение вашей реализации __iadd__ объекту, который вы «добавляете», ПОСЛЕ завершения реализации.

Это означает, что можно изменить левую часть x += y, чтобы завершился неявный шаг. Рассмотрим, что может произойти, когда вы добавляете к чему-то, что находится в списке:

>>> x[1] += y # x has two items

Теперь, если ваша реализация __iadd__ (метод объекта в x[1] ) ошибочно или по назначению удаляет первый элемент (x[0]) с самого начала списка, Python затем запускает ваш метод __iadd__) & amp; попробуйте присвоить его возвращаемое значение x[1]. Который больше не будет существовать (он будет в x[0]), в результате получится ÌndexError.

Или, если ваш __iadd__ вставляет что-то в начало x приведенного выше примера, ваш объект будет находиться в x[2], а не x[1], а все, что было ранее в x[0], будет теперь на x[1] и присваивается возвращаемое значение вызова __iadd__.

Если кто-то не понимает, что происходит, возникающие ошибки могут стать кошмаром для исправления.

13
ответ дан Petri 5 September 2018 в 09:04
поделиться

http://docs.python.org/reference/datamodel.html#emulating-numeric-types

Например, чтобы выполнить оператор x + = y, где x является экземпляром класса, который имеет метод __iadd __ (), вызывается x .__ iadd __ (y).

5
ответ дан Unknown 5 September 2018 в 09:04
поделиться
Другие вопросы по тегам:

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