【发布时间】:2018-10-08 08:44:18
【问题描述】:
我有一个从不同类实例化的对象列表。我想对该列表中某个类的所有对象调用某个方法。我觉得我找到的方式不是很优雅,可能有更好的方式。
目前,我是这样做的:
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
有没有更好的办法?
编辑:澄清问题
我会尽量用简单的方式来说明这个问题,希望我不会用细节来压倒你。
我有一个应用程序与我的网络上的以太网连接的嵌入式站接口。这些站点中的每一个都由不同的类表示,并且每个类都提供了不同的功能来控制该站点。
首先,必须执行扫描,以便我知道网络上实际可用的站点。因此,创建了一个基本的“Station”对象并调用了“scan”。扫描是一个请求,期望来自工作站的答复。如果有答案,它将指定连接站的确切类型。
其次,基本站需要通过第一个扫描步骤刚刚发现的“模式”进行扩展。 “基本”模式被工作站所处的特定模式取代。“基本”模式只允许刚刚执行的扫描。
这是实际的基本站类。 __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
这是“模式”类的示例,例如“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
我制作了所谓的“接口”,它附加到“模式”对象并提供以某种方式控制工作站的功能。我可以将多个接口连接到一个站点,因此它获得了所有接口的功能。
总之,站点可能非常不同,我不确定多态性是否适用。方法不会有相同的名称、功能或参数。
抱歉,如果这里缺少信息或提供的信息过多。
【问题讨论】:
-
如果我理解你想要正确地做的事情,为什么不直接使用多态呢?
-
这看起来确实像一个多态性问题,但是为了确保我们需要知道你的类实际上是什么。您可以编辑您的问题以显示您的实际课程而不是假人吗?
-
这种方法对我来说似乎没有什么问题。它很简洁,可以做你想做的事。您可以使用
map函数和列表理解:map(fn, [obj for obj in objlist if type(obj) is classname]。这样做的问题是,您要从列表推导式构建一个列表,然后使用map对其进行迭代,因此您实际上是迭代了两次,而您的解决方案只循环了一次。 -
我现在扩展了这个问题。您可能是对的,但我不想通过“类”以及“方法”。我宁愿只通过“Class.method”和“execute()”计算出“method”属于哪个类。
标签: python python-3.x iterator