Listy składane z obiektami klas
Mam klasę o nazwie StrucData w subfile.py
class StrucData:
def __init__(self, name):
self.name=name
def loadData(self, size=1, cost=1):
self.size=size
self.cost=cost
W głównym pliku I:
- wywołaj podplik,
- utwórz listę nazw danych
- przejrzyj listę, aby utworzyć instancję obiektów; i
- załaduj dane za pomocą metody „loadData” dla każdego obiektu (używam tego samego „rozmiaru” i „kosztu”, aby ułatwić ten przykład).
from subfile import StrucData
listIndex=['data1','data2','data3']
# Create a list of objects
listObjects=[]
# Iterate through the list of objects
for i in range(3):
data=StrucData(listIndex[i])
data.loadData(size=3, cost=4)
listObjects.append(data)
To, co próbuję zrobić, to zrobić to samo, używając rozumienia list, aby uzyskać
listObjects=[object1, object2, object3]
i próbowałem czegoś takiego
listObjects=[[StrucData(listIndex[i]) for k in range(3)] listObjects[i].loadData(size=3, cost=4) for i in range(3)]]
co oczywiście nie działa, ale nie wiem, jak to zrobić poprawnie.
Czy mógłbym prosić o radę na temat mojego kodu, aby uzyskać żądane wyniki za pomocą rozumienia listy?
Odpowiedzi
Jeśli możesz dołączyć return self
do ostatniego wiersza w StrucData.loadData()
ciągu subfile.py
, można to uprościć w następujący sposób:
# in the main file
listObjects = [StrucData(idx).loadData(size=3, cost=4) for idx in listIndex]
W przeciwnym razie musisz to zrobić osobno, ponieważ loadData()
nie zwróci niczego dla wyrażenia listy.
listObjects = [StrucData(idx) for idx in listIndex]
for i in range(3):
listObjects[i].loadData(size=3, cost=4)
Uzupełniając odpowiedź Billa Huanga, jeśli nie możesz zmieniać obiektu i nie chcesz powtarzać iteracji, możesz dodać funkcję pomocniczą:
def load_data(idx, size, cost):
result = StructData(idx)
result.loadData(size, cost)
return result
[load_data(x, size=3, cost=4) for x in range(3)]
Na marginesie, jeśli tak naprawdę nie potrzebujesz, aby instancja miała oddzieloną nazwę i loadData, możesz po prostu użyć namedtuple:
from collections import namedtuple
StructData = namedtuple('StructData', ['name', 'size', 'cost'])
print([StructData(name=x, size=3, cost=4) for x in range(3)])
Który zwróciłby:
[StructData(name=0, size=3, cost=4),
StructData(name=1, size=3, cost=4),
StructData(name=2, size=3, cost=4)]
Wreszcie, widząc, że masz takie nazwy, jak „dane1”, „dane2”, możesz chcieć je mieć jako nazwy klas, możesz to zrobić za pomocą namedtuple, o ile nazwy są prawidłowymi identyfikatorami klas:
from collections import namedtuple
list_index = ['data1', 'data2', 'data3']
print([namedtuple(name, ['size', 'cost'])(3, 4) for name in list_index])
Wynik:
[data1(size=3, cost=4), data2(size=3, cost=4), data3(size=3, cost=4)]