Автор оригинала: Pankaj Kumar.
Доходность Python – генератор функции реальных образцов жизни
- Ключевое слово «Доходность Python» используется для создания генератора Функция Отказ
- Доходность ключевое слово . Может использоваться только внутри функционального тела.
- Когда функция содержит выражение доходности, он автоматически становится функцией генератора.
- Функция генератора возвращает итератор, известный как генератор.
- Генератор контролирует выполнение функции генератора.
- Когда генератор Next () впервые вызывается, функция генератора запускает его выполнение.
- Когда следующий () метод вызывается для генератора, он выполняет функцию генератора для получения следующего значения. Функция выполняется из того места, где она остановилась и не выполняет полный код функции.
- Генератор внутренне поддерживает текущее состояние функции и ее переменные, так что следующее значение извлекается правильно.
- Вообще, мы используем для петли Чтобы извлечь все значения из функции генератора, а затем обрабатывать их один за другим.
- Функция генератора выгодно, когда функция возвращает огромное количество данных. Мы можем использовать выражение доходности, чтобы получить только ограниченный набор данных, затем обработать его, а затем получить следующий набор данных.
Доходность Python против возврата
- Отчет о возврате Возвращает значение из функции, а затем функция завершается. Выходное выражение преобразует функцию в генератор для возврата значений один за другим.
- Заявление о возврате Python не подходит, когда мы должны вернуть большое количество данных. В этом случае выражение доходности полезно вернуть только часть данных и сохранить память.
Пример урожайности Python
Допустим, у нас есть функция, которая возвращает список случайных чисел.
from random import randint def get_random_ints(count, begin, end): print("get_random_ints start") list_numbers = [] for x in range(0, count): list_numbers.append(randint(begin, end)) print("get_random_ints end") return list_numbers print(type(get_random_ints)) nums = get_random_ints(10, 0, 100) print(nums)
Выход:
get_random_ints start get_random_ints end [4, 84, 27, 95, 76, 82, 73, 97, 19, 90]
Он отлично работает, когда ценность «подсчета» не слишком велико. Если мы укажем счет как 100000, то наша функция будет использовать много памяти для хранения этого много значений в списке.
В этом случае с использованием ключевого слова доходности полезно создать функцию генератора. Давайте преобразуем функцию в функцию генератора и используйте итератор генератора, чтобы получить значения один за другим.
def get_random_ints(count, begin, end): print("get_random_ints start") for x in range(0, count): yield randint(begin, end) print("get_random_ints end") nums_generator = get_random_ints(10, 0, 100) print(type(nums_generator)) for i in nums_generator: print(i)
Выход:
get_random_ints start 70 15 86 8 79 36 37 79 40 78 get_random_ints end
- Обратите внимание, что тип NUMS_Generator – генератор.
- Первое оператор печати выполняется только один раз, когда первый элемент извлекается от генератора.
- Оказавшись, все элементы даются от функции генератора, оставшийся код в функции генератора выполнен. Вот почему второе утверждение печати напечатано только один раз и в конце цикла.
Python Generator Функция реального мира примера
Один из самых популярных примеров использования генераторной функции – прочитать большой текстовый файл. Для этого я создал два сценария Python.
- Первый скрипт читает все файловые строки в список, а затем вернуть его. Тогда мы печатаем все линии к консоли.
- Второй сценарий использует ключевое слово «Доходность», чтобы прочитать одну строку одновременно и вернуть его к абонеру. Тогда это напечатано на консоль.
Я использую модуль ресурсов Python для распечатки памяти и использования времени как скриптов.
read_file.py
import resource import sys def read_file(file_name): text_file = open(file_name, 'r') line_list = text_file.readlines() text_file.close() return line_list file_lines = read_file(sys.argv[1]) print(type(file_lines)) print(len(file_lines)) for line in file_lines: print(line) print('Peak Memory Usage =', resource.getrusage(resource.RUSAGE_SELF).ru_maxrss) print('User Mode Time =', resource.getrusage(resource.RUSAGE_SELF).ru_utime) print('System Mode Time =', resource.getrusage(resource.RUSAGE_SELF).ru_stime)
read_file_yield.py
import resource import sys def read_file_yield(file_name): text_file = open(file_name, 'r') while True: line_data = text_file.readline() if not line_data: text_file.close() break yield line_data file_data = read_file_yield(sys.argv[1]) print(type(file_data)) for l in file_data: print(l) print('Peak Memory Usage =', resource.getrusage(resource.RUSAGE_SELF).ru_maxrss) print('User Mode Time =', resource.getrusage(resource.RUSAGE_SELF).ru_utime) print('System Mode Time =', resource.getrusage(resource.RUSAGE_SELF).ru_stime)
У меня есть четыре текстовых файла разных размеров.
~ du -sh abc.txt abcd.txt abcde.txt abcdef.txt 4.0K abc.txt 324K abcd.txt 26M abcde.txt 263M abcdef.txt ~
Вот статистика, когда я бегу как скрипты для разных файлов.
~ python3.7 read_file.py abc.txt Peak Memory Usage = 5558272 User Mode Time = 0.014006 System Mode Time = 0.008631999999999999 ~ python3.7 read_file.py abcd.txt Peak Memory Usage = 10469376 User Mode Time = 0.202557 System Mode Time = 0.076196 ~ python3.7 read_file.py abcde.txt Peak Memory Usage = 411889664 User Mode Time = 19.722828 System Mode Time = 7.307018 ~ python3.7 read_file.py abcdef.txt Peak Memory Usage = 3917922304 User Mode Time = 200.776204 System Mode Time = 72.781552 ~ python3.7 read_file_yield.py abc.txt Peak Memory Usage = 5689344 User Mode Time = 0.01639 System Mode Time = 0.010232999999999999 ~ python3.7 read_file_yield.py abcd.txt Peak Memory Usage = 5648384 User Mode Time = 0.233267 System Mode Time = 0.082106 ~ python3.7 read_file_yield.py abcde.txt Peak Memory Usage = 5783552 User Mode Time = 22.149525 System Mode Time = 7.461281 ~ python3.7 read_file_yield.py abcdef.txt Peak Memory Usage = 5816320 User Mode Time = 218.961491 System Mode Time = 74.030242
Вот данные в табличном формате для лучшего понимания.
4 КБ | Память: 5,3 МБ, время: 0,023 | Память: 5,42 МБ, время: 0,027с |
324 кб | Память: 9,98 МБ, время: 0,028с | Память: 5,37 МБ, время: 0,32с |
26 МБ. | Память: 392,8 МБ, время: 27,03 | Память: 5,52 МБ, время: 29,61 |
263 МБ | Память: 3,65 ГБ, время: 273,56 | Память: 5,55 МБ, время: 292.99 |
Таким образом, функция генератора принимает немного дополнительное время, чем оператор возврата. Это очевидно, потому что он должен отслеживать состояние функции в каждом итераторе следующий () вызов.
Но, с ключевым словом доходности. Преимущества памяти огромны. Использование памяти напрямую пропорционально размеру файла с оператором возврата. Это почти постоянно с функцией генератора.
Примечание : Пример вот показать преимущества использования ключевогое доходности, когда функция производит большое количество данных. Файл Python уже имеет встроенную функцию readline () для чтения линейки данных файла по строке, которая является эффективной памятью, быстрыми и простыми в использовании.
Python ready Express Пример
В предыдущих примерах функция генератора отправляет значения звонящему. Мы также можем отправлять значения в функцию генератора, используя функцию отправки ().
Когда функция отправки () вызывается для запуска генератора, он должен быть вызван ни в качестве аргумента, потому что нет выражения выхода, которое может получить значение. В противном случае мы получим TypeError: не может отправить нераспределенное значение для простота генератора Отказ
def processor(): while True: value = yield print(f'Processing {value}') data_processor = processor() print(type(data_processor)) data_processor.send(None) for x in range(1, 5): data_processor.send(x)
Выход:
Processing 1 Processing 2 Processing 3 Processing 4
Доходность Python из примера
«Выход из выражения» используется для создания субгитератора от заданного выражения. Все значения, создаваемое субгитератором, передаются непосредственно в программу вызывающего абонента. Допустим, мы хотим создать обертку для функции get_random_ints ().
def get_random_ints(count, begin, end): print("get_random_ints start") for x in range(0, count): yield randint(begin, end) print("get_random_ints end") def generate_ints(gen): for x in gen: yield x
Мы можем использовать функцию «Выход из» в функции Generate_ints () для создания двунаправленного соединения между программой вызывающего абонента и субгитератором.
def generate_ints(gen): yield from gen
Фактическое преимущество «доходности от» видна, когда мы должны отправлять данные в функцию генератора. Давайте посмотрим на пример, когда функция генератора принимает данные от вызывающего абонента и отправляет его в поддитератор для его обработки.
def printer(): while True: data = yield print("Processing", data) def printer_wrapper(gen): # Below code to avoid TypeError: can't send non-None value to a just-started generator gen.send(None) while True: x = yield gen.send(x) pr = printer_wrapper(printer()) # Below code to avoid TypeError: can't send non-None value to a just-started generator pr.send(None) for x in range(1, 5): pr.send(x)
Выход:
Processing 1 Processing 2 Processing 3 Processing 4
Это много кода для создания функции обертки. Мы можем просто использовать «доходность от» здесь, чтобы создать функцию обертки, и результат останется прежним.
def printer_wrapper(gen): yield from gen
Заключение
Ключевое слово «Доходность Python» создает генераторную функцию. Это полезно, когда функция возвращает большое количество данных, расщепляя его в несколько кусков. Мы также можем отправлять значения генератору, используя функцию отправки (). «Уход от» оператора используется для создания субгитератора из функции генератора.