Создание функции, которая принимает другую функцию в качестве аргумента

#python #function

Вопрос:

Я хотел бы создать функцию, которая могла бы сделать следующий фрагмент повторно используемым:

 # !pip install Faker
from faker import Faker

[Faker().credit_card_number() for _ in range(5)]
 

Я пробовал использовать:

 def generate_data(faker_function):
  return [faker_function for _ in range(5)]
 

Однако generate_data(Faker().credit_card_number())
Приводит к тому, что функция вызывается один раз и копируется

 ['4852671922370639',
 '4852671922370639',
 '4852671922370639',
 '4852671922370639',
 '4852671922370639']
 

Как я могу добиться этой реализации?

Комментарии:

1. Потому Faker().credit_card_number() что генерирует новое число. И то же самое. Это передается в качестве аргумента, который добавляется в список 5 раз

2. Есть ли обходной путь для использования его в функции?

3. Не связаны, но в чем смысл класса Faker , а не в использовании обычной функции?

Ответ №1:

Вы передаете там переменную, а не функцию

Попробуй

 def generate_data(faker_function):
  return [faker_function() for _ in range(5)]

f = Faker()
generate_data(f.credit_card_number)  
 

В частности, вы передаете дескриптор функции, а затем вызываете функцию, как в противном случае, если бы она не была параметром

Обратите внимание, что это не совсем то же самое, что и первый фрагмент, потому что это создает 5 уникальных экземпляров класса Faker, и в нем используется только один

Комментарии:

1. Отличный Ответ. Но я почти собирался опубликовать то же самое!

2. Операция передает результат вызова метода, а не сам метод. Определение f = Faker() не имеет существенного значения.

3. @chep Согласился, но извлечение его можно использовать повторно, если по какой-либо причине им понадобилось настроить подделку

4. @Люк, пожалуйста, поясни

5. Не имеет значения, используете ли вы f. или Faker(). Ответ здесь заключается в том, что вам нужно переместить скобки при фактическом вызове функции

Ответ №2:

generate_data должен получить связанный метод, а не результат вызова метода, в качестве аргумента, а затем вызвать полученный аргумент внутри функции:

 def generate_data(faker_function):
    return [faker_function() for _ in range(5)]

generate_data(Faker().credit_card_number)
 

Комментарии:

1. Передача связанного метода также приводит к появлению списка связанных методов [<bound method Provider.credit_card_number of <faker.providers.credit_card.en_US.Provider object at 0x7ffb9c1cc4f0>>, <bound method Provider.credit_card_number of <faker.providers.credit_card.en_US.Provider object at 0x7ffb9c1cc4f0>>, <bound method Provider.credit_card_number of <faker.providers.credit_card.en_US.Provider object at 0x7ffb9c1cc4f0>>, <bound method Provider.credit_card_number of ]

2. Вам нужно будет вызвать переданную функцию @Luke

3. Тьфу, пропустил эту часть.

4. Что ж, этот ответ-именно то, что я искал ! Спасибо @chepner