Как объявить защищенные члены в Python3 [duplicate]

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], как могут предположить некоторые.

28
задан Martijn Pieters 12 May 2014 в 17:00
поделиться

2 ответа

ключевые слова с шаблоном __ * являются частными именами классов.

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()

31
ответ дан Sean 20 August 2018 в 09:57
поделиться
  • 1
    __spam будет преобразовано в _Ham__spam, так как это было испорчено уценкой. – Karl Knechtel 22 June 2011 в 20:28
  • 2
    Правильное место для просмотра в руководстве было именно тем, что я искал. Спасибо. – Jason A 22 June 2011 в 20:29
  • 3
    @Karl - Хороший глаз! – Sean 22 June 2011 в 21:21
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.

0
ответ дан Marko 20 August 2018 в 09:57
поделиться
  • 1
    Не уверен, что это то же самое происходит здесь, так как vars не искажены, как __ vars. – Adam Wagner 5 October 2012 в 00:19
Другие вопросы по тегам:

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