При определении оси X вы можете изменить его, добавив в него «Тип» и установить значение «категория». По умолчанию библиотека просматривает данные, пытаясь определить тип для вас, если он не указан. Вот как должны выглядеть ваши изменения:
JFIDDLE : http://jsfiddle.net/xa1uy5dz/
[110 ]
Справочная информация: https://plot.ly/javascript/reference/#layout-xaxis-type
>>> a = 89
>>> id(a)
4434330504
>>> a = 89 + 1
>>> print(a)
90
>>> id(a)
4430689552 # this is different from before!
>>> test = [1, 2, 3]
>>> id(test)
48638344L
>>> test2 = test
>>> id(test)
48638344L
>>> test2 += [4]
>>> id(test)
48638344L
>>> print(test, test2) # [1, 2, 3, 4] [1, 2, 3, 4]```
([1, 2, 3, 4], [1, 2, 3, 4])
>>> id(test2)
48638344L # ID is different here
Мы видим, что, когда мы пытаемся изменить неизменный объект (целое число в этом случае), Python просто дает нам другой объект вместо этого. С другой стороны, мы можем внести изменения в изменяемый объект (список) и иметь его остаются тем же объектом повсюду.
Также относятся ниже URL для понимания shallowcopy и deepcopy
https://www.geeksforgeeks.org/copy-python-deep-copy-shallow-copy /
Для общего случая см. ответ Скотта Гриффита . Однако при работе со списками, как вы, оператор + =
является сокращением для someListObject.extend (iterableObject)
. См. документацию по extend () .
Функция extend
добавит все элементы параметра в список.
Выполняя foo + = something
, вы изменяете список foo
на месте, таким образом, вы не меняете ссылку, на которую указывает имя foo
на, но вы изменяете объект списка напрямую. Используя foo = foo + something
, вы фактически создаете новый список.
Этот пример кода объясняет это:
>>> l = []
>>> id(l)
13043192
>>> l += [3]
>>> id(l)
13043192
>>> l = l + [3]
>>> id(l)
13059216
Обратите внимание, как ссылка изменяется, когда вы переназначаете новый список на l
.
Поскольку bar
является переменной класса, а не переменной экземпляра, изменение на месте повлияет на все экземпляры этого класса. Но при переопределении self.bar
экземпляр будет иметь отдельную переменную экземпляра self.bar
, не затрагивая другие экземпляры класса.
Общий ответ таков: + =
пытается вызвать специальный метод __ iadd __
, и если это недоступен, он пытается использовать вместо этого __ add __
. Итак, проблема в различии этих специальных методов.
Специальный метод __ iadd __
предназначен для добавления на месте, то есть он изменяет объект, на который действует. Специальный метод __ add __
возвращает новый объект и также используется для стандартного оператора +
.
Итак, когда оператор + =
используется для объекта, для которого задано значение __ iadd __
, объект изменяется на месте. В противном случае вместо этого он попытается использовать простой __ add __
и вернет новый объект.
Вот почему для изменяемых типов, таких как списки + =
, изменяется значение объекта, тогда как для неизменяемых типов, таких как кортежи, строки и целые числа, вместо этого возвращается новый объект ( a + = b
становится эквивалентным a = a + b
).
Для типов, поддерживающих как __ iadd __
, так и __ add __
, вы должны быть осторожны с тем, какой из них используете. a + = b
вызовет __ iadd __
и изменит a
, тогда как a = a + b
создаст новый объект и назначит его a
. Это не одна и та же операция!
>>> a1 = a2 = [1, 2]
>>> b1 = b2 = [1, 2]
>>> a1 += [3] # Uses __iadd__, modifies a1 in-place
>>> b1 = b1 + [3] # Uses __add__, creates new list, assigns it to b1
>>> a2
[1, 2, 3] # a1 and a2 are still the same list
>>> b2
[1, 2] # whereas only b1 was changed
Для неизменяемых типов (где у вас нет __ iadd __
) a + = b
и a = a + b
эквивалентны. Это то, что позволяет вам использовать + =
для неизменяемых типов, что может показаться странным дизайнерским решением, пока вы не поймете, что в противном случае вы не могли бы использовать + =
для неизменяемых типов, таких как числа!
Проблема в том, что bar
определяется как атрибут класса, а не как переменная экземпляра.
В foo
атрибут класса изменен в методе init
, поэтому затрагиваются все экземпляры.
В foo2
переменная экземпляра определяется с использованием атрибута (пустого) класса, и каждый экземпляр получает свою собственную полосу
.
«Правильная» реализация:
class foo:
def __init__(self, x):
self.bar = [x]
Конечно, атрибуты класса полностью допустимы. Фактически, вы можете получить к ним доступ и изменить, не создавая экземпляр класса следующим образом:
class foo:
bar = []
foo.bar = [x]