#python
#python
Вопрос:
В python переменная имеет имя, а объект — нет (поскольку несколько переменных могут указывать на один и тот же объект)
Но есть ли способ добавить / изменить name
свойство объекта, когда оно присваивается переменной.
В идеале, что-то, что работало бы следующим образом:
spam = MagicObject()
print(spam.name) # output: "spam"
ham = spam
print(spam.name) # output: "ham"
Редактировать: На самом деле, я действительно не возражаю, если вторая печать будет «ветчина» или «спам», поскольку я действительно не планирую, чтобы несколько переменных указывали на один и тот же объект. Я просто хочу, чтобы у объекта было имя независимо от сценария.
Моя идея состоит в том, чтобы создать какой-то файл параметров с как можно меньшим количеством записей. Чтобы этот простой код:
person_id = PrimaryKey()
создал бы объект PrimaryKey и автоматически назвал бы его «person_id»
Комментарии:
1. Нет.
spam
практически невозможно узнать, что оно было присвоено чему-либо, не говоря уже об имени правопреемника2. @PhxDev вообще не связан с тем, что пытается сделать OP
3. Кроме того, что, по-вашему, произойдет, если мы это сделаем
a, b = spam, spam
?4. Переменные являются просто заполнителями в алгоритме. Их конкретное имя не должно иметь значения, тем более что вы иногда ограничены в именах, которые вы можете использовать для данной переменной, и, следовательно, не можете присвоить ей какое-либо конкретное значение.
5. Это выполнимо с помощью атрибутов класса, например,
class Foo: bar = Baz()
, а затем большого количества метаклассов или__init__
магии… Но для автономных переменных это плохая идея.
Ответ №1:
Я думаю, что это максимально приближено к тому, что вы пытаетесь сделать. Это неэффективно и злоупотребляет globals
и properties
. Кроме того, если MagicObject
это сложно, это нужно будет реализовать __eq__
(и, вероятно __hash__
, также хорошо).
Это взлом, и, вероятно, его не следует использовать в производстве.
class MagicObject:
@property
def name(self):
return [k for k, v in globals().items() if v == self]
a = MagicObject()
print(a.name)
b = a
print(a.name)
c = a
print(a.name)
del b
print(a.name)
Выводит
['a']
['a', 'b']
['a', 'b', 'c']
['a', 'c']
Также имейте в виду, что в Python < 3.7 порядок списка будет произвольным, поскольку словари не имеют порядка.
Комментарии:
1. Это, конечно, неэффективно, но я не вижу здесь злоупотреблений.
Globals
иproperty
для меня это абсолютно верные инструменты. Вы можете сделать это произвольным списком с помощьюreturn sorted([k for k, v in globals().items() if v == self])
. В любом случае, я действительно не планирую иметь несколько переменных для объекта. Я просто хотел уточнить, что объект может иметь уникальное (хотя и несколько произвольное) имя, что бы ни случилось.2. Я думаю, вам следует заменить
v==self
наv is self
. Нет необходимости переопределять__eq__
таким образом, и в любом случае это более логично3. @Madlozoz Не обязательно, это полностью зависит от реализации
MagicObject
и того, чего вы пытаетесь достичь, как я объяснил в своем ответе. В случае, если__eq__
не определено,==
в любом случае возвращается кis
Ответ №2:
Похоже, вы хотите написать ORM. Два предложения:
- Не делайте этого. Используйте уже написанный, например, SQLAlchemy.
- Если вы делаете что-то еще, или вы действительно хотите спуститься в эту кроличью нору, проверьте, как эти ORM делают это, скорее всего, с помощью метакласса.