python - 将多个类方法应用于对象列表的 Pythonic 方式
问题描述
我有一个带有一些内置方法的类。这是该类可能看起来的抽象示例:
class Foo:
def __init__(self):
self.a = 0
self.b = 0
def addOneToA(self):
self.a += 1
def addOneToB(self):
self.b += 1
为了简单起见,我将内置方法减少到 2 个,但实际上我的班级接近 20 个。
接下来我有另一个类,旨在处理Foo
实例列表。
class Bar:
def __init__(self, fooInstances):
self.fooInstances = fooInstances
# Bar([Foo(), Foo(), Foo()])
如果我想将其中一种Foo
方法应用于 中的Foo
实例Bar
怎么办?
class Bar:
# ...
def addOneToA(self):
for fooInstance in self.fooInstances:
fooInstance.addOneToA()
def addOneToB(self):
for fooInstance in self.fooInstances:
fooInstance.addOneToB()
上面的示例是执行我所描述的一种方式,但如果有 20 个Foo
. 或者,我可以这样做:
class Bar:
# ...
def applyFooMethod(self, func, *args):
for fooInstance in self.fooInstances:
fooInstance.func(args)
但我更希望有一些东西可以让我调用并将.addOneToA()
其Bar
应用于. 有没有一种干净的方法可以在不定义inside的所有方法的情况下做到这一点?Foo
Bar
Foo
Bar
解决方案
一种方法是__getattr__
覆盖Bar
:
class Bar:
def __init__(self, fooInstances):
self.fooInstances = fooInstances
def __getattr__(self, attr):
try:
getattr(self.fooInstances[0], attr)
except AttributeError:
raise AttributeError(f"'Bar' object has no attribute '{attr}'")
else:
def foo_wrapper(*args, **kwargs):
for foo_inst in self.fooInstances:
getattr(foo_inst, attr)(*args, **kwargs)
return foo_wrapper
__getattr__
Bar
如果对Bar
对象的属性查找失败,则调用 on。然后我们尝试查看一个Foo
实例是否具有该属性;如果不是,则引发一个,AttributeError
因为既不Bar
也不Foo
接受该属性。但是如果Foo
确实有它,我们会返回一个函数,当被调用时,它会在驻留在对象attr
中的每个瞬间调用方法 () 。Foo
Bar
用法:
...
# changed this method in Foo to see the passing-an-argument case
def addOneToA(self, val):
self.a += 1
print(f"val = {val}")
...
>>> bar = Bar([Foo(), Foo(), Foo()])
>>> bar.addOneToB()
>>> [foo.b for foo in bar.fooInstances]
[1, 1, 1]
>>> bar.addOneToA(val=87) # could also pass this positionally
val = 87
val = 87
val = 87
>>> bar.this_and_that
AttributeError: 'Bar' object has no attribute 'this_and_that'
推荐阅读
- selenium - 如何使用 UI.Vision RPA 扩展播放 html 视频
- javascript - Google Apps 脚本日历服务:如何使用 PropertiesService 存储和检索 CalendarEvents?
- sql - 如何在创建之前从下一个插入元素中获取 id?
- macros - 在 Scheme Hygienic Macros 中取消引用拼接等效项
- nginx - LinkedIn 后检查员给出 500 次失败
- android - 如何在计算着色器中最好地访问 ARCore 视频帧
- python - 编写一个接受数字列表和单个数字作为参数的函数。该函数应打印所有小于数字的数字
- python - 在 python 中创建确定性的 UUID 集
- sql - sql server中基于join的转置
- google-sheets - 谷歌表格,条件格式,如果“旁边”的单元格具有相同的值,请检查每个单元格