Здесь есть две вещи:
1. class attributes and instance attributes
2. difference between the operators + and += for lists
+
оператор вызывает метод __add__
в списке. Он берет все элементы из своих операндов и создает новый список, содержащий эти элементы, поддерживающие их порядок.
+=
оператор вызывает метод __iadd__
в списке. Он требует итерации и добавляет все элементы итерабельности в список на месте. Он не создает новый объект списка.
В классе foo
оператор self.bar += [x]
не является оператором присваивания, но фактически переводит на
self.bar.__iadd__([x]) # modifies the class attribute
, который изменяет список на месте и действует как метод списка extend
.
В классе foo2
, наоборот, оператор присваивания в методе init
self.bar = self.bar + [x]
может быть деконструирован как: экземпляр не имеет атрибута bar
(есть атрибут класса с тем же именем), поэтому он обращается к атрибуту class bar
и создает новый список, добавляя к нему x
. Оператор преобразуется в:
self.bar = self.bar.__add__([x]) # bar on the lhs is the class attribute
Затем он создает атрибут экземпляра bar
и присваивает ему вновь созданный список. Обратите внимание, что bar
на rhs присваивания отличается от bar
на lhs.
Для экземпляров класса foo
, bar
является атрибутом класса, а не атрибутом экземпляра. Следовательно, любое изменение атрибута class bar
будет отражено для всех экземпляров.
Напротив, каждый экземпляр класса foo2
имеет свой собственный атрибут экземпляра bar
, который отличается от атрибута класса с тем же именем bar
.
f = foo2(4)
print f.bar # accessing the instance attribute. prints [4]
print f.__class__.bar # accessing the class attribute. prints []
Надеюсь, это очистит.
Со страницы проекта android-apt
:
Плагин android-apt помогает в работе с процессорами аннотаций в сочетании с Android Studio. Он имеет две цели:
Позволяет настроить процессор аннотаций только времени компиляции в качестве зависимости, не включая артефакт в конечном APK или библиотеке
Установите исходные пути так, чтобы код, сгенерированный из процессора аннотаций, был правильно подобран Android Studio.
Вы используете Dagger, который использует обработку аннотаций для генерации кода. Код обработки аннотации не должен быть включен в окончательный APK, и вы хотите, чтобы сгенерированный код был виден Android Studio. android-apt
позволяет это поведение.
Это звучит очень похоже на объем provided
, но apt
отличается от provided
в нескольких ключевых аспектах. Первое отличие состоит в том, что код, сгенерированный зависимостью apt
, доступен для IDE, тогда как код, сгенерированный зависимостью provided
, недоступен.
Другое важное отличие состоит в том, что код в библиотеке, использующей область действия provided
, находится в пути к классам IDE (то есть вы можете импортировать классы и пытаться использовать их), тогда как код в зависимости apt
- нет. С provided
ваш код будет аварийно завершаться во время выполнения, если вы на самом деле не предоставите ссылочные зависимости с compile
областью действия.
Вы можете найти обсуждение apt
против provided
на этой android-apt
проблеме .
В случае с Dagger не должно быть никаких причин включать процессор аннотаций и генератор кода в любой ваш код (что позволит область provided
). Таким образом, объем apt
является более подходящим.
Обновление за октябрь 2016: Возможно, вам больше не нужен apt
и плагин android-apt
. Версия 2.2 плагина Android Gradle имеет конфигурацию annotationProcessor
, которую вы должны использовать вместо этого.
Подробнее на Что дальше для android-apt?