Как передать функции с аргументами в качестве параметра другой функции в Python с именем функции в виде строки? - PullRequest
0 голосов
/ 21 ноября 2018

У меня есть следующий исходный код в main.py

main.py

import data_utils as du

X_train1, Y_train1, groundtruth_train1= du.loaddata(train_file, "adjust_gamma", 0.8)
X_train2, Y_train2, groundtruth_train2= du.loaddata(train_file, "adjust_gamma", 1.2)
X_train3, Y_train3, groundtruth_train3= du.loaddata(train_file, "scale_image", 0.5)
X_train4, Y_train4, groundtruth_train4= du.loaddata(train_file, "scale_image", 0.8)
X_train5, Y_train5, groundtruth_train5= du.loaddata(train_file, "scale_image", 1.5)
X_train6, Y_train6, groundtruth_train6= du.loaddata(train_file, "scale_image", 2.0)
X_train7, Y_train7, groundtruth_train7= du.loaddata(train_file, "compress_jpeg", 70)
X_train8, Y_train8, groundtruth_train8= du.loaddata(train_file, "compress_jpeg", 90)

main.py будет читать несколько изображений, применять преобразования изображений, делить их на блоки (этомои выводы X_train) и получить метки изображений (Y_train и groundtruth_train).Преобразование изображения определяется строкой с параметрами (например, «Adjust_gamma» и т. Д.).

Теперь load_data.py был построен на основе этого ответа о том, как передавать функции с аргументами в другойfunction

data_utils.py

def loaddata(file_images, function_name, parameter):

x = []
y = []

with open(file_images) as f:
    images_names = f.readlines()
    images_names = [a.strip() for a in images_names]

    j=0

    for line in images_names:

        j=j+1

        line='image_folder/' + line
        img = cv2.imread(img_path)
        img=perform(eval(function_name)(img,parameter)) 
        ...

Функция, которую выполняет функция, получит имя функции (в виде строки, как вы можете видеть в main.py) и ее параметры (изображение в numpy)массив и параметры).Выполненная функция подробно описана ниже:

def perform(fun, *args):
fun(*args)

def adjust_gamma(image, gamma):
   invGamma = 1.0 / gamma
   table = np.array([((i / 255.0) ** invGamma) * 255
      for i in np.arange(0, 256)]).astype("uint8")
   return cv2.LUT(image, table)

def compress_jpeg(image, compression_factor):
   encode_param=[int(cv2.IMWRITE_JPEG_QUALITY), compression_factor]
   result, encimg=cv2.imencode('.jpg', image, encode_param)
   decimg=cv2.imdecode(encimg, 1)
   return decimg

def scale_image(image, scaling_factor):
   resized_image=cv2.resize(image, (scaling_factor, scaling_factor))
   return resized_image 

Я пытался использовать функцию eval, чтобы передаваемая строка могла рассматриваться как имя функции ( Этот ответ вдохновил меня на это ).Однако, когда я запускаю код, я получаю следующую ошибку:

Файл "main.py", строка 32, в do_experiment

X_train1, Y_train1, groundtruth_train1 = du.loaddata (train_file, "Adjust_Gamma", 0,8)

Файл "data_utils.py", строка 29, в loaddata

img = execute (eval (имя_функции) (img, параметр)) Файл "data_utils.py ",

строка 171, в исполнении fun (** args) TypeError: объект 'numpy.ndarray' не вызывается

Итак, как мне решить мою проблему?Как я могу передать функцию в качестве аргументов другой функции, используя имя функции в виде строки?

1 Ответ

0 голосов
/ 21 ноября 2018

Замените eval(function_name)(img,parameter) на:

globals()[function_name](img,parameter)

Обратите внимание, что в моем ответе нужная функция должна быть в том же модуле, в противном случае прочитайте эту ссылку или Это о globals и locals в python, чтобы найти лучшее решение для вашей проблемы.

Кроме того, вы можете получить доступ к функции другого модуля с помощью getattr, например:

getattr(module, func)(*args, **kwargs)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...