2016-06-16 4 views
2

Я использую экземпляры пользовательского класса (аналогично 2D-вектору с кучей лишних вещей, среди прочего) в качестве ключа dict.
Он использует собственный хэш и равен магическим методам, который в основном делает его равным кортежу с данными инициализации.python access dict key по ключевому слову

Набор данных, с которым я столкнулся, настолько велик, что память (ОЗУ) является основной проблемой, и мне нужны несколько разных структур данных с теми же экземплярами пользовательских объектов, что и ключи.

Я хочу получить доступ к фактической ссылке ключей dict.

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

Возможно ли это? И если да, то как?

Пример:

dict1 = {} 
dict2 = {} 

Один сегмент кода:

v = MyVect(1,5,"data",True) 
dict1[v] = ("important", "data") 

Второй сегмент:
(. Эта часть имеет доступ только к данным, который был использован для создания MyVect, но без фактической ссылки)

keydata_without_reference = (1,5,"data",True) 
mykey = dict1.getkeyref(keydata_without_reference) # getkeyref somehow 
dict2[mykey] = "some other data" 

В результате I w ould экономит почти половину памяти.
Это просто настройка исходных структур данных, которые программа использует позже.

+0

Ваши случайные изменения в терминах немного запутывают, но код помогает. Например, нет такой вещи, как «2D-вектор» (это матрица), и ваш код использует только простые 4-кортежи. – Prune

+0

Теперь ... что мешает вам использовать один и тот же вектор для каждого из них (структура данных)?Словарь Python делает для вас собственное хеширование. – Prune

+0

Я не знаю, как правильно это сформулировать, но похоже, что вы не понимаете, что я пытаюсь объяснить. Я имею в виду термин «вектор», не похожий на вектор C++, который более или менее переводится в список python (динамический массив), но как математический вектор, используемый в играх и т. Д. Это объект с данными, указывающий на уникальную точку в моделируемой среды. Так что, это просто куча данных, которые вы также можете представить в кортеже, но кортежи не могут представлять состояние с помощью методов и т. Д. –

ответ

1

Что вы хотите сделать, по существу, - это управлять созданием экземпляров MyVect, чтобы при заданном наборе данных инициализации был создан только один экземпляр MyVect.

Я бы предложил использовать Factory method pattern, реализованный как статический метод класса MyVect, который будет отслеживать все экземпляры класса, которые были созданы.

class MyVect(object): 

    instances = {} 

    @staticmethod 
    def get_instance(*args): 
     instance = MyVect.instances.get(args) 
     if instance is None: 
      MyVect.instances[args] = instance = MyVect(*args) 
     return instance 

    def __init__(*args): 
     # Memory intensive initialization here 

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

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

keydata_without_reference = (1,5,"data",True) 
mykey = MyVect.get_instance(*keydata_without_reference) 
dict2[mykey] = "some other data" 

В языках с контролем доступа к методам и атрибутам (как C++, Java и т.д.), вы должны установить конструктор класса для частного, который заставит код вызова использовать фабричный метод для получения и избегать любых проблем. В Python это невозможно, поэтому вам нужно быть осторожным, чтобы напрямую не ссылаться на конструктор.

+0

Спасибо, это решение, но для этого потребовалось бы много рефакторинга, потому что его рабочий проект, который просто неизученно переросл ограничения начальной реализации. Кстати. Конкретный конструктор комментариев не должен быть проблемой из-за небольшого размера команды. Я думаю, что вы несколько не поняли мой вопрос, но ваш ответ правильный, без изменений xD. Есть только экземпляры Myaect maaaany, а не только несколько с массивными данными в них. Я подожду, ответ отвечу на один или два дня на другие ответы, потому что я все еще надеюсь на более легкое решение для рефакторинга. –

+0

Вы правы, я не уверен, что понимаю, что вы пытаетесь сделать. Вы хотите иметь меньше экземпляров 'MyVect', правильно? У вас их много, потому что у вас есть несколько экземпляров для заданного набора данных инициализации или из-за того, что у вас одинаковое количество наборов данных инициализации? – jstlaurent

Смежные вопросы