Не может использовать список методов в классе Python, это нарушает глубокую копию.Обходной путь? - PullRequest
2 голосов
/ 11 апреля 2011

Я пытаюсь узнать больше о Python, внедрив классификатор k-Nearest Neighbor.KNN работает, маркируя новые данные, основываясь на том, на что существующие данные больше всего похожи.Таким образом, для данной таблицы данных вы пытаетесь определить 3 наиболее похожих точки (если k = 3) и выбрать любую метку, которая встречается чаще.Есть разные способы определения «сходства», какая-то функция расстояния.Таким образом, вы можете реализовать различные функции расстояния (косинусное расстояние, манхэттен, евклидово и т. Д.) И выбирать то, что хотите.

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

Вот мой парный класс вниз

class DataTable:

    def __init__(self, filename,TrueSymbol,FalseSymbol):
        self.t = self.parseCSV(filename)
        self.TrueSymbol = TrueSymbol
        self.FalseSymbol = FalseSymbol
        # This is the problem line of code
        self.distList = [self.euclideanDistance,
                            self.manhattanDistance,
                            self.cosineDistance]

    def nearestNeighbors(self,entry,k=None,distanceMetric=None):
        """
        distanceMetrics you can choose from:
        0 = euclideanDistance
        1 = manhattanDistance
        2 = cosineDistance
        """
        if distanceMetric == None:
            distanceFunction = self.euclideanDistance
        else:
            self.distList[distanceMetric]
        # etc..

    def euclideanDistance(self,entry):
        pass
    def manhattanDistance(self,entry):
        pass
    def cosineDistance(self,entry):
        pass

    # open up that csv
    def parseCSV(self,filename):
        pass

А вот код, который вызывает его import import deepcopytestDS import copy

data = deepcopytestDS.DataTable("ionosphere.data","g","b")
deepCopy = copy.deepcopy(data) # crash.

Вот callstack

>>> deepCopy = copy.deepcopy(data)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/copy.py", line 162, in deepcopy
    y = copier(x, memo)
  File "/usr/lib/python2.6/copy.py", line 292, in _deepcopy_inst
    state = deepcopy(state, memo)
  File "/usr/lib/python2.6/copy.py", line 162, in deepcopy
    y = copier(x, memo)
  File "/usr/lib/python2.6/copy.py", line 255, in _deepcopy_dict
    y[deepcopy(key, memo)] = deepcopy(value, memo)
  File "/usr/lib/python2.6/copy.py", line 162, in deepcopy
    y = copier(x, memo)
  File "/usr/lib/python2.6/copy.py", line 228, in _deepcopy_list
    y.append(deepcopy(a, memo))
  File "/usr/lib/python2.6/copy.py", line 189, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "/usr/lib/python2.6/copy.py", line 323, in _reconstruct
    y = callable(*args)
  File "/usr/lib/python2.6/copy_reg.py", line 93, in __newobj__
    return cls.__new__(cls, *args)
TypeError: instancemethod expected at least 2 arguments, got 0

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

1 Ответ

4 голосов
/ 11 апреля 2011

Это была ошибка: http://bugs.python.org/issue1515

Вы можете поместить это вверху файла, чтобы оно заработало:

import copy
import types

def _deepcopy_method(x, memo):
    return type(x)(x.im_func, copy.deepcopy(x.im_self, memo), x.im_class)
copy._deepcopy_dispatch[types.MethodType] = _deepcopy_method
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...