Как правильно передать объекты по значению в функции - PullRequest
0 голосов
/ 03 апреля 2019

У меня есть рекурсивная функция, которая имеет сложные аргументы, такие как массивы и словари объектов. это основная рекурсивная функция,

def finish_top_line(puzzle,result,corner,edge,results):
    min_loss, min_index = 0, 0
    loss_dic = {}
    a_dict = {}
    pieces = {}
    i = len(list(result.keys()))
    print(len(results)," : ",i)
    if i == 1 or i == 25:
        corner.remove(result[i - 1])
    else:
        edge.remove(result[i - 1])
    if i == 25:
    elif i == 24:    
        for index in corner:
            find_corner(puzzle[index], 1,puzzle[result[i-1]])
            result[i] = index
        print("done with 24")
        final = show_results(result, puzzle)
        j = len(results)
        r = ResultSet()
        r.puzzle = puzzle
        r.result = result
        r.corners = corner
        r.edges = edge
        results.append(r)
        name = "result"+ str(j) + ".png"
        print(name)
        final.save(name)    
    else:
        for index in edge:
            left_index = result[i - 1]
            ***important parts***
            loss, a_diff, piece = match_left_right(puzzle[left_index].clone_piece(), puzzle[index].clone_piece())
            pieces[index] = piece
            loss_dic[loss] = index
            if min_loss == 0 or loss < min_loss:
                min_index = index
                min_loss = loss

        s = sorted(loss_dic.keys())
        l = []
        for j in s:
            # p, r, c, e = 0,0,0,0
            if abs(j - min_loss) <= LOSS_RANGE:
                index = loss_dic[j]
                print(index, " : ", j)
                t = deepcopy(puzzle[index])
                puzzle[index] = pieces[index]
                result[i] = index
                ***important parts***
                p, r, c, e = copyPuzzle(puzzle), deepcopy(result), deepcopy(corner), deepcopy(edge)
                finish_top_line(puzzle, r ,c, e,results)

                puzzle = p
                puzzle[index] = t
            else:
                break

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

функция ниже - это функция, вызываемая для копирования словаря объекта. здесь глубокая копия не работала.

def copyPuzzle(puzzle):
    p = {}
    for i in list(puzzle.keys()):
        p[i] = (puzzle[i].clone_piece())
    return p 

это функция клона функции, закодированная под объектом.

def clone_piece(self):
    t = Piece()
    t.edge_type = deepcopy(self.edge_type)
    t.corners = deepcopy(self.corners)
    t.img = deepcopy(Image.fromarray(np.uint8(cv2.cvtColor(np.asarray(self.img), cv2.COLOR_RGB2BGR))))
    t.edge_type = deepcopy(self.edge_type)
    t.index= deepcopy(self.index)
    t.floatCorners = deepcopy(self.floatCorners)
    t =self
    return t

изменения в данных внутри функций аналогичны повороту и изменению размеров изображений. в конце во время тестирования .. данные, кажется, запутались, код продолжает работу и может ясно видеть, что каждое сохраненное изображение более грязное, чем предыдущее. так что эта попытка передать по значению, похоже, не работает. Как я могу это исправить? как правильно передать значение

1 Ответ

1 голос
/ 03 апреля 2019
def clone_piece(self):
    t = Piece()
    t.edge_type = deepcopy(self.edge_type)
    t.corners = deepcopy(self.corners)
    t.img = deepcopy(Image.fromarray(np.uint8(cv2.cvtColor(np.asarray(self.img), cv2.COLOR_RGB2BGR))))
    t.edge_type = deepcopy(self.edge_type)
    t.index= deepcopy(self.index)
    t.floatCorners = deepcopy(self.floatCorners)
    t =self
    return t

Может быть изменено на

def clone_piece(self):
    return deepcopy(self)

Ошибка, которую вы делаете, состоит в том, что эта строка перед возвратом:

t = self

Это в основном отменяет все предыдущие строки

...