Может кто-нибудь помочь мне передать функцию в качестве аргумента в python? - PullRequest
1 голос
/ 11 марта 2020

У меня есть следующий класс в python. Я хочу передать функцию get_priority в качестве аргумента для доступа к объекту Task. Я получаю следующую ошибку при добавлении второй задачи в taskManager:

, если значение == array [int (middle)]. AcessMethod (): AttributeError: Экземпляр задачи не имеет атрибута 'acessMethod'

Класс задач

class Task:

    def __init__(self,id,name,category="",priority=1):
        self.id = id
        self.name = name
        self.category = category
        self.priority = priority
        self.concluded = False
        self.active_days = 0
        print("Beggining Class")

    def get_name(self):
        return self.name

    def get_category(self):
        return self.category

    def get_priority(self):
        return self.priority

    def set_name(self,name):
        self.name = name

    def set_category(self,category):
        self.category = category

    def set_priority(self,priority):
        self.priority = priority

    def __str__(self):
        return str(self.id) + " | " + self.name + " | " + self.category + " | " + str(self.priority) + " | "

Класс TaskManager

from task import Task

class TaskManager(object):
    """docstring forTaskManager."""

    def __init__(self):
        print("Initing TaskManager")
        self.taskArray = []

    """Adding task ordered by priority"""
    """Maibe adding a check for autheticity of the object """
    def addTask(self,task):
        if len(self.taskArray) == 0 or self.taskArray[0].get_priority() <= task.get_priority():
            self.taskArray.insert(0,task)
        else:
            index = self.__binarySearchIndex(task.get_priority,self.taskArray,'get_priority')
            self.taskArray.insert(index,task)

    def __binarySearchIndex(self,value,array,acessMethod):
        middle = (len(self.taskArray) / 2) if ((len(self.taskArray) % 2) == 0) else (len(self.taskArray) / 2) + 1
        if middle == 1:
            middle = 0
        if value == array[middle].acessMethod():
            return middle
        elif value < array[middle].acessMethod():
            self.__binarySearchIndex(value,array[:middle])
        else:
            self.__binarySearchIndex(value,array[middle:])

    def __str__(self):
        taskString = ""
        for task in self.taskArray:
            taskString = taskString + str(task) + " \n"
        return taskString

Ответы [ 3 ]

0 голосов
/ 11 марта 2020

На самом деле я пошел другим путем, вместо того, чтобы вызывать метод по его имени, я просто делаю лямбда-функцию для извлечения любого атрибута, который я хочу, из объекта Task.

class Task:

    def __init__(self,id,name,category="",priority=1):
        self.id = id
        self.name = name
        self.category = category
        self.priority = priority
        self.concluded = False
        self.active_days = 0
        print("Beggining Class")

    def get_name(self):
        return self.name

    def get_category(self):
        return self.category

    def get_priority(self):
        return self.priority

    def set_name(self,name):
        self.name = name

    def set_category(self,category):
        self.category = category

    def set_priority(self,priority):
        self.priority = priority

    def __str__(self):
        return str(self.id) + " | " + self.name + " | " + self.category + " | " + str(self.priority) + " | "

class TaskManager(object):
    """docstring forTaskManager."""

    def __init__(self):
        print("Initing TaskManager")
        self.taskArray = []

    """Adding task ordered by priority"""
    """Maibe adding a check for autheticity of the object """
    def addTask(self,task):
        if len(self.taskArray) == 0 or self.taskArray[0].get_priority() <= task.get_priority():
            self.taskArray.insert(0,task)
        else:
            index = self.__binarySearchIndex(task.get_priority(),self.taskArray, lambda task: task.get_priority())
            self.taskArray.insert(index,task)

    def __binarySearchIndex(self,value,array,accessMethod):
        if len(array) == 0:
            return 0
        middle = (len(self.taskArray) / 2) if ((len(self.taskArray) % 2) == 0) else (len(self.taskArray) // 2) + 1
        if middle == 1:
            middle = 0
        if value == accessMethod(array[middle]):
            return middle
        elif value < accessMethod(array[middle]):
            return middle + self.__binarySearchIndex(value,array[:middle],accessMethod)
        else:
            return middle - self.__binarySearchIndex(value,array[middle:],accessMethod)

    def __str__(self):
        taskString = ""
        for task in self.taskArray:
            taskString = taskString + str(task) + " \n"
        return taskString

if __name__ == "__main__":
    taskA = Task(1, "taskA", priority=2)
    taskB = Task(2, "taskB", priority=1)
    taskC = Task(3, "taskC", priority=1)
    taskD = Task(4, "taskD", priority=3)
    manager = TaskManager()
    manager.addTask(taskA)
    manager.addTask(taskB)
    manager.addTask(taskC)
    manager.addTask(taskD)
    for task in manager.taskArray:
        print(task)

Я также помог немного отладить вашу программу. Начнем с того, что ваши рекурсивные вызовы бинарного поиска не возвращают значений, что вам и нужно.

0 голосов
/ 11 марта 2020

Не передавайте строку, содержащую имя вообще. Используйте функцию methodcaller.

Например:

<b>from operator import methodcaller</b>


class TaskManager(object):

    def __init__(self):
        self.taskArray = []

    def addTask(self, task):
        if (len(self.taskArray) == 0
            or self.taskArray[0].get_priority() <= task.get_priority():
            self.taskArray.insert(0,task)
        else:
            index = self.__binarySearchIndex(
                task.get_priority(),
                self.taskArray,
                <b>methodcaller('get_priority')</b>
            )
            self.taskArray.insert(index, task)

    def __binarySearchIndex(self, value, array, accessMethod):
        middle = (len(self.taskArray) / 2) if ((len(self.taskArray) % 2) == 0) else (len(self.taskArray) / 2) + 1
        if middle == 1:
            middle = 0
        if value == <b>accessMethod(array[middle])</b>:
            return middle
        elif value < <b>accessMethod(array[middle])</b>:
            self.__binarySearchIndex(value,array[:middle])
        else:
            self.__binarySearchIndex(value,array[middle:])

    ...

Если вы упростите свой класс Task, чтобы избавиться от ненужных методов получения и установки:

class Task:

    def __init__(self,id,name,category="",priority=1):
        self.id = id
        self.name = name
        self.category = category
        self.priority = priority
        self.concluded = False
        self.active_days = 0
        print("Beggining Class")

    def __str__(self):
        return str(self.id) + " | " + self.name + " | " + self.category + " | " + str(self.priority) + " | "

, тогда вы можете использовать attrgetter вместо methodcaller.

from operator import <b>attrgetter</b>

class TaskManager(object):

    def __init__(self):
        self.taskArray = []

    def addTask(self, task):
        if (len(self.taskArray) == 0
            or self.taskArray[0].get_priority() <= task.get_priority:
            self.taskArray.insert(0,task)
        else:
            index = self.__binarySearchIndex(
                task.get_priority, 
                self.taskArray,
                <b>attrgetter</b>('get_priority')
            )
            self.taskArray.insert(index, task)

    def __binarySearchIndex(self, value, array, accessMethod):
        middle = (len(self.taskArray) / 2) if ((len(self.taskArray) % 2) == 0) else (len(self.taskArray) / 2) + 1
        if middle == 1:
            middle = 0
        if value == accessMethod(array[middle]):
            return middle
        elif value < accessMethod(array[middle]):
            self.__binarySearchIndex(value,array[:middle])
        else:
            self.__binarySearchIndex(value,array[middle:])

    ...
0 голосов
/ 11 марта 2020

Используйте getattr для получения функции из передаваемой строки

method_to_call = getattr(Task, accessMethod)

if value == array[middle].method_to_call():
...