Я хочу использовать привязки клавиш, но анимация, которую он производит, плохая

Феликс уже дал отличный ответ, но я думал, что сделаю сравнение скорости различных методов:

  1. 10,59 сек (105,9us / itn) - copy.deepcopy(old_list)
  2. 10.16 сек (101.6us / itn) - метод чистого питона Copy(), копирующий классы с глубокой копией
  3. 1.488 сек (14.88us / itn) - чистый питон Copy() метод не копирует классы (только dicts / lists / tuples)
  4. 0,325 с (3,25us / itn) - for item in old_list: new_list.append(item)
  5. 0.217 sec (2.17us / itn) - [i for i in old_list] (понимание списка )
  6. 0,186 с (1,86us / itn) - copy.copy(old_list)
  7. 0,075 сек (0,75 us / itn) - list(old_list)
  8. 0,053 сек (0,53us / itn) - new_list = []; new_list.extend(old_list)
  9. 0,039 сек (0,39us / itn) - old_list[:] ( list slicing )

Таким образом, самая быстрая сортировка списка. Но имейте в виду, что copy.copy(), list[:] и list(list), в отличие от copy.deepcopy() и версии python, не копируют списки, словари и экземпляры класса в списке, поэтому, если оригиналы меняются, они будут меняться в скопированный список тоже и наоборот.

(Вот скрипт, если кто-то заинтересован или хочет поднять какие-либо проблемы:)

from copy import deepcopy

class old_class:
    def __init__(self):
        self.blah = 'blah'

class new_class(object):
    def __init__(self):
        self.blah = 'blah'

dignore = {str: None, unicode: None, int: None, type(None): None}

def Copy(obj, use_deepcopy=True):
    t = type(obj)

    if t in (list, tuple):
        if t == tuple:
            # Convert to a list if a tuple to 
            # allow assigning to when copying
            is_tuple = True
            obj = list(obj)
        else: 
            # Otherwise just do a quick slice copy
            obj = obj[:]
            is_tuple = False

        # Copy each item recursively
        for x in xrange(len(obj)):
            if type(obj[x]) in dignore:
                continue
            obj[x] = Copy(obj[x], use_deepcopy)

        if is_tuple: 
            # Convert back into a tuple again
            obj = tuple(obj)

    elif t == dict: 
        # Use the fast shallow dict copy() method and copy any 
        # values which aren't immutable (like lists, dicts etc)
        obj = obj.copy()
        for k in obj:
            if type(obj[k]) in dignore:
                continue
            obj[k] = Copy(obj[k], use_deepcopy)

    elif t in dignore: 
        # Numeric or string/unicode? 
        # It's immutable, so ignore it!
        pass 

    elif use_deepcopy: 
        obj = deepcopy(obj)
    return obj

if __name__ == '__main__':
    import copy
    from time import time

    num_times = 100000
    L = [None, 'blah', 1, 543.4532, 
         ['foo'], ('bar',), {'blah': 'blah'},
         old_class(), new_class()]

    t = time()
    for i in xrange(num_times):
        Copy(L)
    print 'Custom Copy:', time()-t

    t = time()
    for i in xrange(num_times):
        Copy(L, use_deepcopy=False)
    print 'Custom Copy Only Copying Lists/Tuples/Dicts (no classes):', time()-t

    t = time()
    for i in xrange(num_times):
        copy.copy(L)
    print 'copy.copy:', time()-t

    t = time()
    for i in xrange(num_times):
        copy.deepcopy(L)
    print 'copy.deepcopy:', time()-t

    t = time()
    for i in xrange(num_times):
        L[:]
    print 'list slicing [:]:', time()-t

    t = time()
    for i in xrange(num_times):
        list(L)
    print 'list(L):', time()-t

    t = time()
    for i in xrange(num_times):
        [i for i in L]
    print 'list expression(L):', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        a.extend(L)
    print 'list extend:', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        for y in L:
            a.append(y)
    print 'list append:', time()-t

    t = time()
    for i in xrange(num_times):
        a = []
        a.extend(i for i in L)
    print 'generator expression extend:', time()-t

EDIT: добавлены классы старого стиля и задает тесты, и сделал версию python намного быстрее и добавил еще несколько методов, включая выражения списков и extend().

0
задан Josh Blecherman 24 March 2019 в 02:37
поделиться

1 ответ

Привязки клавиш IIRC ведут себя так же, как при вводе в текстовое поле. В частности, я имею в виду, что если вы удерживаете кнопку (в данном случае клавишу со стрелкой вправо), она отправит нажатие клавиши один раз, а через секунду или две начнется быстрая отправка нажатия клавиши. Вот почему вы получите прерывистое движение, игровой цикл запускается чаще, чем называется привязка.

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

0
ответ дан Hunter L 24 March 2019 в 02:37
поделиться
Другие вопросы по тегам:

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