#python
Вопрос:
Рассмотрим следующий код:
class DummyClass:
def __init__(self, name):
self.name = name
obj_1 = DummyClass("name_1")
obj_2 = DummyClass("name_2")
my_dict = {
obj_1: "value_1",
obj_2: "value_2"
}
print(my_dict)
Выход
{<__main__.DummyClass object at 0x7f8f6493a0b8>: 'value_1', <__main__.DummyClass object at 0x7f8f649869e8>: 'value_2'}
Этот код создал словарь my_dict
, содержащий экземпляры ключей DummyClass
as.
Я хотел бы знать, есть ли волшебная функция (например __something__
), которую я могу переопределить, DummyClass
чтобы приведенный выше код выдавал следующий результат:
{'name_1': 'value_1', 'name_2': 'value_2'}
где name_1
и name_2
являются обеими строками, name
свойствами DummyClass
экземпляров.
Я не хочу менять визуализацию или печать, я хочу на самом деле изменить ключ в памяти.
Комментарии:
1. Не знаю, почему кто-то понизил голос. Если бы я не знал названия функции, которую искал, я не смог бы найти ответ.
2. Я, вероятно, упускаю здесь главное, но мне кажется, что это
my_dict = {obj_1.name: "value_1", obj_2.name: "value_2" }
сделает то, что вы хотите.3. В данном конкретном случае-да. Но есть ли модель общего способа, которая позволила бы мне писать
my_dict = {obj_1: "value_1", obj_2: "value_2" }
и получать те же результаты,my_dict = {obj_1.name: "value_1", obj_2.name: "value_2" }
что и ? Похоже, мне нужно переопределить__repr__
.4. Мне кажется, вы ищете то, что Delphi называет атрибутом по умолчанию : это значение RH имени экземпляра голого класса, которое вы, конечно, должны объявить, иначе что дает
self.name
приоритет над другими атрибутами? Но в Python нет известного мне механизма, позволяющего сделать один атрибут более важным, чем другие. Я думаю, было бы лучше объяснить, почему вы считаете, что вам нужен такой механизм.5. Тогда нет, это невозможно сделать. Сам объект является ключом, нет никакого волшебного метода для «фактического значения, которое будет использоваться в качестве ключа, когда оно используется в качестве ключа словаря» . Как было предложено выше, вы должны указать контекст, проблему, которую это решит.
Ответ №1:
__repr__
Метод используется для генерации строки, которая dict
используется для отображения ключей. Не существует механизма для изменения ключа во dict
время создания или обновления, а dict
также конкретного способа изменения способа отображения ключа.
По умолчанию DummyClass
наследует свой __repr__
метод от object
, который и создает <...>
строку. Переопределение __repr__
для возврата строки, построенной из name
атрибута.
class DummyClass:
def __init__(self, name):
self.name = name
def __repr__(self):
return f"'{self.name}'"
Было предложение создать словарь, преобразующий ключи, но оно было отклонено. Это позволило бы вам написать что-то вроде
d = TransformDict(lambda x: x.name)
d[obj_1] = ...
d[obj_2] = ...
и результат dict
будет вести себя так, как если 'name1'
бы и 'name2'
были ключами (при этом все еще позволяя доступ к исходным ключам obj_1
и obj_2
при необходимости).
Комментарии:
1. Это приведет к правильному печатному представлению, но, как указано в комментариях к вопросу, это не делает фактический ключ словаря строкой; он просто делает его похожим на строку ниже
2. Я недостаточно четко сформулировал это. Либо экземпляр
dict
является ключом, либо это не так.dict
не предоставляет способа изменить ключ во время создания dict (хотя см. Отклоненный PEP-455 , в котором предлагался именно такой механизм) и не предоставляетdict
конкретного крючка для отображения ключа.3. Да, я вовсе не критикую твой ответ. Я просто не хочу, чтобы ОП думал, что это полное решение их проблемы, учитывая, что они прояснили данный вопрос в комментариях. Как написано, это ответ на поставленный вопрос. В комментариях просто есть дополнительный контекст, который я не хочу упускать.
4. Я попытался прояснить ответ таким образом, чтобы он соответствовал первоначальному намерению.
5. Спасибо. Итак, в заключение, сделает ли использование
__repr__
клавиш строками, если__repr__
функция вернет строку?