Добавьте Значок Контекстного меню в андроиде

Для понимания, что yield делает необходимо понять, каковы генераторы . И прежде чем можно понять генераторы, необходимо понять iterables.

Iterables

при создании списка можно считать его объекты один за другим. Чтение его объектов один за другим называют повторением:

>>> mylist = [1, 2, 3]
>>> for i in mylist:
...    print(i)
1
2
3

mylist повторяемы . При использовании понимания списка Вы создаете список, и таким образом, повторяемое:

>>> mylist = [x*x for x in range(3)]
>>> for i in mylist:
...    print(i)
0
1
4

Все можно использовать" for... in..." на, повторяемое; lists, strings, файлы...

Эти iterables удобны, потому что можно считать их так, как Вы желаете, но Вы храните все значения в памяти, и это не всегда, что Вы хотите, когда у Вас есть много значений.

Генераторы

Генераторы являются итераторами, своего рода повторяемое , можно только выполнить итерации по однажды . Генераторы не хранят все значения в памяти, они генерируют значения на лету :

>>> mygenerator = (x*x for x in range(3))
>>> for i in mygenerator:
...    print(i)
0
1
4

Это все равно кроме Вас, использовал () вместо [1 115]. НО, Вы не можете выполнять for i in mygenerator во второй раз, так как генераторы могут только использоваться однажды: они вычисляют 0, затем забывают об этом и вычисляют 1, и конец, вычисляющий 4, один за другим.

Урожай

yield является ключевым словом, которое используется как [1 118], кроме функции возвратит генератор.

>>> def createGenerator():
...    mylist = range(3)
...    for i in mylist:
...        yield i*i
...
>>> mygenerator = createGenerator() # create a generator
>>> print(mygenerator) # mygenerator is an object!

>>> for i in mygenerator:
...     print(i)
0
1
4

Здесь это - бесполезный пример, но удобно, когда Вы будете знать, что Ваша функция возвратит огромный набор значений, которые необходимо будет только считать однажды.

ведущему устройству yield, необходимо понять, что , когда Вы вызываете функцию, код, Вы записали в теле функции, не работает. функция только возвращает объект генератора, это - немного хитрый:-)

Затем Ваш код продолжится от того, где это кончило каждый раз for использование генератор.

Теперь твердая часть:

В первый раз for вызовы, которые объект генератора создал из Вашей функции, он выполнит код в Вашей функции с начала, пока он не совершит нападки yield, тогда он возвратит первое значение цикла. Затем друг друга звонят, выполнит цикл, который Вы записали в функции еще раз и возвращаете следующее значение, пока нет никакого значения для возврата.

генератор считают пустым, как только функция работает, но не совершает нападки yield больше. Это может быть, потому что цикл закончился, или потому что Вы не удовлетворяете "if/else" больше.

Ваш код объяснил

Генератор:

# Here you create the method of the node object that will return the generator
def _get_child_candidates(self, distance, min_dist, max_dist):

    # Here is the code that will be called each time you use the generator object:

    # If there is still a child of the node object on its left
    # AND if the distance is ok, return the next child
    if self._leftchild and distance - max_dist < self._median:
        yield self._leftchild

    # If there is still a child of the node object on its right
    # AND if the distance is ok, return the next child
    if self._rightchild and distance + max_dist >= self._median:
        yield self._rightchild

    # If the function arrives here, the generator will be considered empty
    # there is no more than two values: the left and the right children

Вызывающая сторона:

# Create an empty list and a list with the current object reference
result, candidates = list(), [self]

# Loop on candidates (they contain only one element at the beginning)
while candidates:

    # Get the last candidate and remove it from the list
    node = candidates.pop()

    # Get the distance between obj and the candidate
    distance = node._get_dist(obj)

    # If distance is ok, then you can fill the result
    if distance <= max_dist and distance >= min_dist:
        result.extend(node._values)

    # Add the children of the candidate in the candidate's list
    # so the loop will keep running until it will have looked
    # at all the children of the children of the children, etc. of the candidate
    candidates.extend(node._get_child_candidates(distance, min_dist, max_dist))

return result

Этот код содержит несколько умных частей:

  • цикл выполняет итерации в списке, но список расширяется, в то время как цикл выполняется с помощью итераций:-), Это - краткий способ пройти все эти вложенные данные, даже если это немного опасно, так как можно закончить с бесконечным циклом. В этом случае candidates.extend(node._get_child_candidates(distance, min_dist, max_dist)) выхлоп все значения генератора, но while продолжает создавать новые объекты генератора, которые произведут различные значения из предыдущих, так как это не применяется на тот же узел.

  • extend() метод является методом объекта списка, который ожидает повторяемое и добавляет его значения к списку.

Обычно мы передаем список ему:

>>> a = [1, 2]
>>> b = [3, 4]
>>> a.extend(b)
>>> print(a)
[1, 2, 3, 4]

, Но в Вашем коде, это получает генератор, который хорош потому что:

  1. Вы не должны читать значения дважды.
  2. у Вас может быть много детей, и Вы не хотите их всех сохраненных в памяти.

И это работает, потому что Python не заботится, является ли аргументом метода список или нет. Python ожидает iterables, таким образом, это будет работать со строками, списками, кортежами и генераторами! Это называют утиным вводом и является одной из причин, почему Python так прохладен. Но это - другая история для другого вопроса...

можно остановиться здесь или читать немного для наблюдения усовершенствованного использования генератора:

Управление исчерпанием генератора

>>> class Bank(): # Let's create a bank, building ATMs
...    crisis = False
...    def create_atm(self):
...        while not self.crisis:
...            yield "$100"
>>> hsbc = Bank() # When everything's ok the ATM gives you as much as you want
>>> corner_street_atm = hsbc.create_atm()
>>> print(corner_street_atm.next())
$100
>>> print(corner_street_atm.next())
$100
>>> print([corner_street_atm.next() for cash in range(5)])
['$100', '$100', '$100', '$100', '$100']
>>> hsbc.crisis = True # Crisis is coming, no more money!
>>> print(corner_street_atm.next())

>>> wall_street_atm = hsbc.create_atm() # It's even true for new ATMs
>>> print(wall_street_atm.next())

>>> hsbc.crisis = False # The trouble is, even post-crisis the ATM remains empty
>>> print(corner_street_atm.next())

>>> brand_new_atm = hsbc.create_atm() # Build a new one to get back in business
>>> for cash in brand_new_atm:
...    print cash
$100
$100
$100
$100
$100
$100
$100
$100
$100
...

Примечание: Для Python 3, используйте print(corner_street_atm.__next__()), или print(next(corner_street_atm))

Это может быть полезно для различных вещей как управление доступом к ресурсу.

Itertools, Ваш лучший друг

itertools модуль содержит специальные функции для управления iterables. Когда-нибудь хотите копировать генератор? Цепочка два генератора? Группа оценивает во вложенном списке с остротой? Map / Zip, не создавая другой список?

Тогда всего import itertools.

пример? Давайте посмотрим возможные заказы прибытия для четырех гонок:

>>> horses = [1, 2, 3, 4]
>>> races = itertools.permutations(horses)
>>> print(races)

>>> print(list(itertools.permutations(horses)))
[(1, 2, 3, 4),
 (1, 2, 4, 3),
 (1, 3, 2, 4),
 (1, 3, 4, 2),
 (1, 4, 2, 3),
 (1, 4, 3, 2),
 (2, 1, 3, 4),
 (2, 1, 4, 3),
 (2, 3, 1, 4),
 (2, 3, 4, 1),
 (2, 4, 1, 3),
 (2, 4, 3, 1),
 (3, 1, 2, 4),
 (3, 1, 4, 2),
 (3, 2, 1, 4),
 (3, 2, 4, 1),
 (3, 4, 1, 2),
 (3, 4, 2, 1),
 (4, 1, 2, 3),
 (4, 1, 3, 2),
 (4, 2, 1, 3),
 (4, 2, 3, 1),
 (4, 3, 1, 2),
 (4, 3, 2, 1)]

Понимание внутренних механизмов повторения

Повторение является процессом, подразумевающим iterables (реализация __iter__() метод) и итераторы (реализующий __next__() метод). Iterables являются любыми объектами, от которых можно получить итератор. Итераторы являются объектами, которые позволяют Вам выполнить итерации на iterables.

существует больше об этом в этой статье [приблизительно 1 135] как for работа циклов .

16
задан Segfault 4 March 2010 в 17:37
поделиться

2 ответа

Контекстные меню не поддерживают значки.

Примечание: Контекст пункты меню не поддержка значков или сочетаний клавиш.

39
ответ дан 30 November 2019 в 15:44
поделиться

Хотя Android API не разрешает использование значков в Контекстных меню, вы можете видеть много мест, где Android использует их. Длительное нажатие на главный экран является одним из хороших примеров.

Я нашел время, чтобы покопаться в источниках Launcher и AnyCut и обнаружил, что Google использует свой собственный пользовательский класс, который расширяет BaseAdapter вместе с их собственной пользовательской раскладкой.

Мне удалось почти точно скопировать их класс и макет и использовать его в своем собственном приложении. Класс, если вы хотите его найти, называется AddAdapter.java.

Наслаждайтесь!

2
ответ дан 30 November 2019 в 15:44
поделиться
Другие вопросы по тегам:

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