myList = [[1]*4] * 3
создает один объект списка [1,1,1,1]
в памяти и копирует его ссылку 3 раза. Это эквивалентно obj = [1,1,1,1]; myList = [obj]*3
. Любая модификация obj
будет отражена в трех местах, где obj
упоминается в списке. Правильным утверждением будет:
myList = [[1]*4 for _ in range(3)]
или
myList = [[1 for __ in range(4)] for _ in range(3)]
. Важно отметить, что *
оператор в основном используется для создания список литералов. Поскольку 1
является литералом, значит, obj =[1]*4
создаст [1,1,1,1]
, где каждый 1
будет атомарным, а не ссылкой 1
, повторяемым 4 раза. Это означает, что если мы obj[2]=42
, то obj
станет [1,1,42,1]
не [42,42,42,42]
, как могут предположить некоторые.
ключевые слова с шаблоном __ * являются частными именами классов.
http://docs.python.org/reference/lexical_analysis.html#reserved-classes-of-identifiers
Цитата:
Имена этой категории, используемые в контексте определения класса, переписываются, чтобы использовать искаженную форму, чтобы избежать конфликтов имен между «частными» атрибутами базового и производного классов
Частное имя mangling (выделено мной):
Управление частным именем: когда идентификатор, который имеет текстовое значение в определение класса начинается с двух или более символов подчеркивания и не заканчивается двумя или более символами подчеркивания, оно считается частным именем этого класса. Частные имена преобразуются в более длинную форму до того, как для них генерируется код. Преобразование вставляет имя класса перед именем, с удалением ведущих подчеркиваний и одним подчеркиванием, вставленным перед именем класса. Например, идентификатор
__spam
, входящий в класс с именем Ham, будет преобразован в_Ham__spam
. Это преобразование не зависит от синтаксического контекста, в котором используется идентификатор. Если преобразованное имя чрезвычайно длинное (длиннее 255 символов), может быть реализовано определенное усечение. Если имя класса состоит только из символов подчеркивания, преобразование не выполняется.http://docs.python.org/reference/expressions.html#atom-identifiers
Это означает, что за кулисами
B.__a()
преобразуется в нечто вродеB._B__a()
In [1]: class A(object):
...: def __init__(self):
...: self.a()
...: def a(self):
...: print "A.a()"
...:
...: __str__ = a
...:
In [2]: class B(A):
...: def __init__(self):
...: super(B, self).__init__()
...: def a(self):
...: print "B.a()"
...:
...:
In [3]: b = B()
print str(b)
A.a()
Вам нужно будет снова объявить __str__
в B.
__spam
будет преобразовано в_Ham__spam
, так как это было испорчено уценкой. – Karl Knechtel 22 June 2011 в 20:28