The comments gave the answer:
class Car:
def __init__(self, arg1, arg2):
pass # ...
class Boat:
def __init__(self, arg1, arg2, arg3):
pass # ...
def load_csv(filename: str, cls: type) -> list:
arr = []
with open(filename) as csv_file:
data = iter(csv.reader(csv_file))
next(data) # Discard header
for row in data:
arr.append(cls(*row))
return arr
cars = load_csv("car.csv", Car)
Classes are first class objects that can be passed around, so just pass the class in question.
To invoke it, just call the argument that received the class object as if it were the class. In my modification of your code above, I used *row instead of row to expand the row into one argument per item in the row (cls(*[arg1, arg2, arg3]) is equivalent to cls(arg1, arg2, arg3)) -- this way your classes accept arguments as usual, rather than accepting a single argument holding a list of the instantiation arguments.
One other modification would be to use a CSV DictReader and pass the arguments as keyword arguments:
class Car:
def __init__(self, make, model):
pass # ...
def load_csv(filename: str, cls: type):
arr = []
with open(filename) as csv_file:
reader = csv.DictReader(csv_file)
for record in reader:
arr.append(cls(**record))
return arr
cars = load_csv("car.csv", Car)
DictReader returns each CSV row as a dictionary with keys taken from the header row. This then uses **record to translate the dictionary into keyword arguments for the invocation.
Given car.csv as...
"make","model"
"Toyota","Prius"
"Honda","Accord"
"Ford","F150"
This would return the array of 3 cars instantiated as Car(make="Toyota", model="Prius"), Car(make="Honda", model="Accord"), and Car(make="Ford", model="F150").
car = load("car.csv", Car)? That's a callable returning aCarinstance.class Car. You should just be able to pass in:car = load("car.csv", Car)and then inside the function:arr.append(cls(row))cls(*row), but otherwise yes.csv.readerdoesn't neediter()- you can directly assingdata = csv.reader(...)and usenext(data)andfor row in data: