У меня есть список объектов, которые были созданы из разных классов. Я хочу вызвать определенный метод для всех объектов определенного класса в этом списке. Я чувствую, что способ, который я нашел, не очень элегантен, и, возможно, есть лучший.
В настоящее время я делаю это так:
def execute(fn, classname, objlist):
'''
The function that iterates over all objects,
finds the fitting ones, and executes the chosen "fn"
'''
for obj in objlist:
# Checks for the class from which the object was instantiated
if type(obj) is classname:
# Execute the function.
fn(obj)
class C():
def myfn(self):
print("foo")
class D():
def otherfn(self):
print("bar")
objlist = []
objlist.append(C())
objlist.append(D())
execute(C.myfn, C, objlist)
execute(D.otherfn, D, objlist)
Вывод:
foo
bar
Есть ли лучший способ?
Редактировать: Для выяснения проблемы
Я постараюсь проиллюстрировать проблему простым способом, и я надеюсь, что я не завалю вас подробностями.
У меня есть приложение, которое взаимодействует со встроенными станциями, подключенными к Ethernet, в моей сети. Каждая из этих станций представлена отдельным классом, и каждый класс предоставляет различные функции для управления этой станцией.
Во-первых, необходимо выполнить сканирование, чтобы я знал, какие станции фактически доступны в сети. Поэтому создается базовый объект «Станция» и вызывается «сканирование». Сканирование - это запрос, который ожидает ответа от станции. Если ответ есть, в нем будет указан точный тип подключенной станции.
Во-вторых, базовая станция должна быть расширена на «режим», который был только что обнаружен этим первым шагом сканирования. «Базовый» режим заменяется конкретным режимом, в котором находится станция. «Базовый» режим позволяет только что выполнить это сканирование.
Это фактический класс базовой станции. __LinkUI содержит некоторую информацию о вещах, которые были введены в пользовательский интерфейс, например диапазоны IP-адресов и порты:
class Station(__LinkUI):
'''
Generic class for creating a station. This is used first for
stations that have no known type yet
'''
def __init__(self, ip, storage):
super().__init__(storage)
# IP Address of this station
self.ip = ip
# The handling object for the TCP connection to this station
self.handler = Handler(self.storage.network.confport, self.pool)
# Last response value to a request message
self.response = None
# mode of this station. This is an object that details
# some functions and variables for controlling a certain
# type of station. "Basic" is the default mode with
# no special functions
self.mode = Basic(self)
# Hardware architecture of a station, like DDS/PLL
self.architecture = None
Это пример класса «mode», такого как «Boot», который представляет станцию, находящуюся в режиме загрузчика. Этот «режим» расширяет функциональные возможности объекта «Станция».
class Boot(__Mode):
'''
Extends a station by the boot mode
'''
def __init__(self, station):
self.name = "Boot"
super().__init__(self, station)
# The interface for using the flash mode of the boot station
self.flashInterface = FlashInterface(station)
self.healthInterface = HealthInterface(station)
def flash(self, callback, data):
self.flashInterface.flash(callback, data)
def run(self, callback):
self.flashInterface.run(callback)
__ Mode - это базовый класс, который связывает некоторые переменные и генерирует «Messenger», который используется для генерации реальных необработанных сообщений, отправляемых на станции:
class __Mode():
'''
Base class for different station modes (Boot, Rx, Tx, Central)
'''
def __init__(self, child, station):
# Generate a messenger object for this kind of station
self.messenger = GetMessenger(child)
# Connect variables
self.station = station
station.mode = child
station.name = child.name
station.messenger = child.messenger
Я сделал так называемые «Интерфейсы», которые присоединяются к объектам «Режима» и предлагают функции для управления станцией определенным образом. Я могу подключить несколько интерфейсов к одной станции, поэтому она получает функции всех из них.
В заключение, станции могут быть очень разными, и я не уверен, применим ли полиморфизм. Методы не будут иметь одинаковые имена, функции или параметры.
Извините, если вам не хватает информации или ее слишком много.