Распаковка переменных экземпляра путем создания итерируемого контейнера
Я просто хочу иметь возможность распаковать переменные экземпляра класса foo, например:
x = foo("name", "999", "24", "0.222")
a, b, c, d = *x
a, b, c, d = [*x]
Я не уверен, какой метод является правильным для реализации моего собственного __iter__
Метод, однако, последний, который работал со смешанным "успехом". Я говорю смешанный, потому что выполнение с представленным кодом, кажется, изменяет исходный объект экземпляра x
, так что это больше не действует.
class foo:
def __init__(self, a, b, c, d):
self.a = a
self.b = b
self.c = c
self.d = d
def __iter__(self):
return iter([a, b, c, d])
Я прочитал множество постов на этом сайте относительно __iter__
, __next__
, генераторы и т. д., а также книгу по питону и docs.python.org и, кажется, не в состоянии понять, чего я не понимаю. Я понял, что __iter__
должен возвращать итеративный (который может быть просто self
, но я не уверен, как это работает для того, что я хочу). Я также пробовал различные способы поиграть с реализацией __next__
и перебирая vars(foo).items()
либо путем приведения к списку, либо в виде словаря, но безуспешно.
Я не верю, что это повторяющаяся запись, потому что единственные похожие вопросы, которые я видел, представляют один атрибут объекта последовательности списка или используют диапазон чисел вместо четырех неконтейнерных переменных.
2 ответа
Если вы хотите переменные экземпляра, вы должны получить к ним доступ с помощью .self
:
def __iter__(self):
return iter([self.a, self.b, self.c, self.d])
с этим изменением,
a, b, c, d = list(x)
вы получите переменные.
Вы можете перейти на более рискованный метод использования vars(x)
или же x.__dict__
отсортируйте его по имени переменной (и поэтому оно также ограничено, переменные сохранены в произвольном порядке) и извлеките второй элемент каждого кортежа. Но я бы сказал, что итератор определенно лучше.
Вы можете хранить аргументы в атрибуте (self.e
ниже) или вернуть их при вызове функции:
class foo:
def __init__(self, *args):
self.a, self.b, self.c, self.d = self.e = args
def __call__(self):
return self.e
x = foo("name", "999", "24", "0.222")
a, b, c, d = x.e
# or
a, b, c, d = x()