gpt4 book ai didi

python - 通过接受替换函数作为参数,允许在 __init__ 期间重写对象方法

转载 作者:行者123 更新时间:2023-12-01 04:19:12 25 4
gpt4 key购买 nike

假设我有一个类 (Rectangle),它实现了一个方法 (describe),如下所示:

class Rectangle(object):
def __init__(self, height, width):
self.height = height
self.width = width

def describe(self):
return 'Rectangle with height {:0.2f} and width {:0.2f}'.format(float(self.height),
float(self.width))

这按预期工作:

r = Rectangle(5, 3)
r.describe()
>>> 'Rectangle with height 5.00 and width 3.00'

我希望能够在实例化时指定一个替代函数来代替describe。我相信以下方法有效:

import functools as ft

class RectangleEnhanced(object):
def __init__(self, height, width, description_function=None):
self.height = height
self.width = width
if description_function is None:
self.describe = self.default_describe
else:
self.describe = ft.partial(description_function, self)

def default_describe(self):
return 'Rectangle with height {:0.2f} and width {:0.2f}'.format(float(self.height),
float(self.width))

这样:

s = RectangleEnhanced(5, 3)
s.describe()
>>> 'Rectangle with height 5.00 and width 3.00'

继续像以前一样工作,但是,此外:

def area_description(enh_rect):
return 'Rectangle with area {:0.2f}'.format(float(enh_rect.height * enh_rect.width))

t = RectangleEnhanced(5, 3, area_description)
t.describe()
>>> 'Rectangle with area 15.00'

这是解决这个问题的合理方法吗?我无法想象我是第一个想要这样做的人,所以我很紧张下面的方法是次优的/非Pythonic的/坏的/等等。有“正确”的方法来处理这个问题吗?

<小时/>

编辑

这是一个更接近我的用例的示例:

class FilterableCollection(object):
def __init__(self, items, owner, purpose, filterfunc=None):
self.items = set(items)
self.owner = owner
self.purpose = purpose
if filterfunc is None:
self.filterfunc = lambda x: True
else:
self.filterfunc = ft.partial(filterfunc, self)

def filtered(self):
return filter(self.filterfunc, self.items)

items = ['fun_ball', 'boring_ball', 'fun_bear', 'boring_bear']
owner = 'Bill'
purpose = 'fun'

f = FilterableCollection(items, owner, purpose)
print f.filtered()

def is_applicable(self, item):
return self.purpose in item
g = FilterableCollection(items, owner, purpose, is_applicable)
print g.filtered()

返回:

['fun_bear', 'fun_ball', 'boring_ball', 'boring_bear']
['fun_bear', 'fun_ball']
正如预期的那样。因此,我们的想法是,当您创建 FilterableCollection 的特定实例时,您可以创建一个自定义过滤器(这可能取决于该特定 FitlerableCollection 的其他属性),然后该过滤器可用随时被调用。因此可能有 10 个 FilterableCollections float ,并且可以通过调用 .filtered 方法使用各自的过滤器对它们进行过滤。

我对通过继承或任何其他技术来实现这一点的想法持非常开放的态度。但在这种情况下这将如何应用呢?

最佳答案

The essence is that for each instance of the class, I want to be able to perform a certain kind of filtering on some data attached to the instance. Depending on the context, the kind of filtering required could vary widely.

您在此处描述的内容被称为 strategy pattern ,并且您的示例实现几乎尽可能Pythonic - Python函数是对象,在大多数主流语言中,相当多需要完整的“仿函数”类的设计模式都是用Python中的普通函数实现的。

我能看到的唯一“改进”是摆脱部分 - Python 函数确实知道如何成为实例方法:

    if description_function is None:
self.describe = self.default_describe
else:
self.describe = description_function.__get__(self)

您可以阅读此内容以了解有关此行为的更多信息:https://wiki.python.org/moin/FromFunctionToMethod

这并不是说这会改变纯粹的功能(没有双关语),但它肯定会让你看起来像一个 PythonGuru(tm)

关于python - 通过接受替换函数作为参数,允许在 __init__ 期间重写对象方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33923003/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com