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

Доходность Python – генератор функции реальных образцов жизни

Ключевое слово «Доходность Python» используется для создания функции генератора. Выход VS Python VS Оператор возврата, выход Python от пример генератора, функция отправки () генератора.

Автор оригинала: 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.

  1. Первый скрипт читает все файловые строки в список, а затем вернуть его. Тогда мы печатаем все линии к консоли.
  2. Второй сценарий использует ключевое слово «Доходность», чтобы прочитать одну строку одновременно и вернуть его к абонеру. Тогда это напечатано на консоль.

Я использую модуль ресурсов 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

Заключение

Ключевое слово «Доходность Python» создает генераторную функцию. Это полезно, когда функция возвращает большое количество данных, расщепляя его в несколько кусков. Мы также можем отправлять значения генератору, используя функцию отправки (). «Уход от» оператора используется для создания субгитератора из функции генератора.

Использованная литература: