gpt4 book ai didi

创建幂等方法的 Pythonic 方法

转载 作者:行者123 更新时间:2023-11-28 17:57:16 26 4
gpt4 key购买 nike

让我们创建一个带有start 方法的类。它可以被调用多次,但实际的启动代码应该只执行一次。随后的调用不应执行任何操作。 (一个花哨的词是幂等)

听起来很简单:

class C:
def __init__(self):
self._started = False

def start(self):
if self._started:
return
# start code
print('start')
self._started = True

问题是必须在所有派生方法中重复测试:

class C2(C):
def start(self):
if self._started: # don't forget!
return
# additional code
super().start()
# additional code

我的解决方案 #1:

我将 start 分成两个函数:

class C:
def __init__(self):
self._started = False

def start(self):
# DO NOT OVERRIDE THIS ONE
if self._started:
return
self._start()
self._started = True

def _start(self):
# start code
print('start!')

class C2(C):
def _start(self):
# additional code
super()._start()
# additional code

第二次尝试在第一次调用后将 start 方法替换为 noop func(准确地说,它在实例中创建了一个 noop 函数,它隐藏了类中的方法,但效果是一样的)。

class C:
def start(self):
# start code
print('start!')
self.start = lambda: None

class C2(C):
def start(self):
# additional code
super().start()
# additional code

我对我的解决方案不满意,你知道更好的吗?

更新:我不喜欢的地方:

#1: 要修改start,你不能触摸start,而是修改其他函数

#2:是自修改代码

最佳答案

在派生类中重写的内容可能不是公共(public)接口(interface)的元素,而是实现该接口(interface)的部分的一些内部函数的想法被称为non-virtual interface pattern。 . (当一个公共(public)方法有多个这样的部分时,它通常被称为“模板方法”。)该术语来自 C++(最初来自 Simula),因为只有 virtual 函数可以 被覆盖。当然,Python 依赖于(许多)此类事物的约定,但该模式同样适用于它。

因此,您的解决方案 #1 不足为奇且合理;另一方面,#2 依赖于一个很少使用的特性,它不适用于 super 或像 C.start(self) 这样的手动调用。

关于创建幂等方法的 Pythonic 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57643752/

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