Рубрики
Без рубрики

Использование генераторов Python, чтобы избежать дополнительных вызовов обслуживания

Это мой первый пост на Dev.to, и на самом деле мой первый публичный пост в Интернете, который не является Twee … с меткой Python, Generators, Beginters, Tips.

Это мой первый пост на Dev.to, и на самом деле мой первый публичный пост в Интернете, который не является твитом. Отзывы очень приветствуются!:)

Я уже давно использую генераторы Python, приходилось иметь дело с большими Django Querysets Чтение больших файлов Excel и возможность сохранять память с помощью генераторов стало частью моей повседневной работы. Тем не менее, в наши дни я столкнулся с другой проблемой, когда хотел избежать дополнительных вызовов в услуги и решить их генераторами. Это то, о чем этот пост.

Предположим, вы хотите проверить, дается ли данное user_email зарегистрирован в любой Из следующих социальных сетей: Facebook, Github или Twitter.

def has_facebook_account(user_email):
    print('calling Facebook service')
    return False

def has_github_account(user_email):
    print('calling Github service')
    return True

def has_twitter_account(user_email):
    print('calling Twitter service')
    return True

def has_social_media_account(user_email):
    print('Checking social media apps...')
    # Python's `any` receives an Iterable
    # and returns True when the first truthy clause is found.
    response = any([
        has_facebook_account(user_email),  # This is False
        has_github_account(user_email),  # This is True
        has_twitter_account(user_email),  # This is True
    ])
    print('Done!')
    return response

Что не так с приведенным выше подходом? Ну, если вы запустите его локально, вы увидите следующий вывод:

>>> has_social_media_account('fake@email.com')
Checking social media apps...
calling Facebook service  # This is False, keep going...
calling Github service  # This is True! I can stop now...
calling Twitter service  # Oh no!
Done!

Проблема в том, что список оценивается, как только это будет создано (напротив Lazy Evaluation ). Таким образом, если это список вызовов методов, все вызовы будут выполнены.

На данный момент я подумал, что проблема заключалась в том, что я был на самом деле Призыв Методы при инициализации списка. Так что, возможно, соблюдение только методов ссылок и использование Понимание списка Сделал бы свое дело:

def has_social_account(user_email):
    calls = [has_facebook_account, has_github_account, has_twitter_account]  # Refs
    return any([call(user_email) for call in calls])

Ну, это не сработало, как я хотел. Как я уже говорил, Список полностью оценивается при его создании Анкет В примере выше, он сначала обязательно вызовет все методы, чтобы список был Полностью построенный , имея все оценки всех его элементов – что, в свою очередь, означает, что все методы называются. Понимание списка также не знает о его контексте, то есть он не знает, что оно используется в качестве аргумента для Любые(...) .

Как я это решил? С помощью генератора.

def has_social_account(user_email):
    calls = [has_facebook_account, has_github_account, has_twitter_account]
    return any((call(user_email) for call in calls))  # Note the ( ) instead of [ ]

>>> has_social_account('fake@email.com')
calling Facebook service  # This is False, keep going...
calling Github service  # Aw yeah!

(Call (user_email) для вызовов в вызовах) оценивает генератор (не полностью встроенный список), который затем используется любой Анкет любой (...) Уилл Итатерация над элементами генератора, оценки один за раз Анкет Таким образом, никаких дополнительных звонков не проводится на один раз любой Оценивает второй элемент ( has_github_account (user_email) -> true ), любой Функция оценивается сама, возвращая Верно и не называть третий метод обслуживания ( has_twitter_account ).

Вот суть, если вам интересно Анкет

Пожалуйста, дайте мне знать в комментариях ниже, если что -то не ясно и/или, если вы хотите иметь более подробную статью о генераторах Python.

Оригинал: “https://dev.to/gcrsaldanha/using-python-generators-to-avoid-extra-service-calls-pl”