В приведенном ниже классе Java определены два метода search
. Они различаются по типу searchSpec
. Насколько я понимаю, когда откуда-то вызывается метод search
, проверяется тип searchSpec
, и в зависимости от этого типа вызывается правильный метод search
.
Теперь я реализовал этот класс на Python, используя абстрактные базовые классы. И GuitarSpec
, и MandolinSpec
наследуются от моего абстрактного базового класса и имеют собственный метод matches
. Но у меня нет возможности создать два метода search
в Inventory
, потому что тип аргументов не имеет значения в Python.
Это означает, что в Python при вызове метода search
объекта Inventory
существует вероятность того, что будет возвращен список, содержащий объекты Guitar
и Mandolin
. Итак, мне хотелось бы знать, как я могу получить то же преимущество проверки ввода типа Java, каким-то образом реализованного в Python, чтобы я мог гарантировать, что метод search
возвращает только инструменты того же типа класса.
Это класс Java.
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class Inventory {
private List inventory;
public Inventory() {
inventory = new LinkedList();
}
public void addInstrument(String serialNumber, double price,
InstrumentSpec spec) {
Instrument instrument = null;
if (spec instanceof GuitarSpec) {
instrument = new Guitar(serialNumber, price, (GuitarSpec)spec);
} else if (spec instanceof MandolinSpec) {
instrument = new Mandolin(serialNumber, price, (MandolinSpec)spec);
}
inventory.add(instrument);
}
public Instrument get(String serialNumber) {
for (Iterator i = inventory.iterator(); i.hasNext(); ) {
Instrument instrument = (Instrument)i.next();
if (instrument.getSerialNumber().equals(serialNumber)) {
return instrument;
}
}
return null;
}
public List search(GuitarSpec searchSpec) {
List matchingGuitars = new LinkedList();
for (Iterator i = inventory.iterator(); i.hasNext(); ) {
Guitar guitar = (Guitar)i.next();
if (guitar.getSpec().matches(searchSpec))
matchingGuitars.add(guitar);
}
return matchingGuitars;
}
public List search(MandolinSpec searchSpec) {
List matchingMandolins = new LinkedList();
for (Iterator i = inventory.iterator(); i.hasNext(); ) {
Mandolin mandolin = (Mandolin)i.next();
if (mandolin.getSpec().matches(searchSpec))
matchingMandolins.add(mandolin);
}
return matchingMandolins;
}
}
Это класс Python.
class Inventory:
def __init__(self):
self.instruments: List[Union[Guitar, Mandolin]] = []
def add_instrument(self, serial_number: str, price: float, spec: Union[GuitarSpec, MandolinSpec]):
if isinstance(spec, GuitarSpec):
instrument = Guitar(serial_number, price, spec)
else:
instrument = Mandolin(serial_number, price, spec)
self.instruments.append(instrument)
def get(self, serial_number) -> Union[Guitar, Mandolin, None]:
for instrument in self.instruments:
if instrument.serial_number == serial_number:
return instrument
return None
def search(self, search_spec: Union[GuitarSpec, MandolinSpec]) -> List[Union[Guitar, Mandolin]]:
matching_instruments = []
for instrument in self.instruments:
if instrument.get_spec().matches(search_spec):
matching_instruments.append(instrument)
return matching_instruments