对不起,标题太简单了,请随时编辑更好的标题。
我想编写类似于以下代码的类似开关的方法(.on()
和off()
):
class Hello:
def on(self):
self.say(1)
def off(self):
self.say(2)
def say(self, param):
# a lot of code common to .on() and .off()
# specific code for .() and .off()
if param == 1:
print("hello")
if param == 2:
print("goodbye")
# more code common to both cases
h = Hello()
h.on()
h.off()
.on()
和.off()
共享了很多我想重用的代码(=在方法之间不重复),但是上面的两阶段方法似乎比较笨拙。
是否存在更好的方法之间共享代码的方法?
我想到的另外两个想法(但不知道它们是否可以实现):
答案 0 :(得分:0)
我认为最Python化的方式是使用装饰器
from functools import wraps
def _say(func):
@wraps(func)
def inner(self, *args, **kwargs):
print("set up") # preprocessing code
func(self, *args, **kwargs) # unique code
print("tear down") # postprocessing code
return inner
class Hello:
@_say
def on(self):
print("hello")
@_say
def off(self):
print("goodbye")
用法
Hello().on()
set up
hello
tear down
Hello().off()
set up
goodbye
tear down
请注意,inner
和func
之间的通信数据将需要作为参数/返回值传递。
另一种经典方法是放弃单个方法,而只使用带有参数的方法(可能是布尔值,字符串或枚举),如下所示:
from enum import Enum
class State(Enum):
OFF = 0
ON = 1
class Hello:
def say(self, state):
print('set up')
if state == State.ON:
print('hello')
elif state == State.OFF:
print('goodbye')
else:
raise ValueError
print('tear down')
答案 1 :(得分:0)
您可以在此处使用两种模式,一种是装饰器,另一种是上下文管理器:
让我们实现上下文管理器:
import contextlib
class Hello:
def on(self):
with self.say():
print("hello")
def off(self):
with self.say():
print("goodbye")
@contextlib.contextmanager
def say(self):
# a lot of code common to .on() and .off()
# specific code for .() and .off()
print("before code")
yield
print("after code")
# more code common to both cases
h = Hello()
h.on()
h.off()
通过实现说作为上下文管理器,它使我们可以轻松运行设置代码和拆卸代码。
答案 2 :(得分:0)
新尝试:
class wrap:
before = "_before"
after = "_after"
def __init__(self, before=None, after=None):
if before is not None:
self.before = before
if after is not None:
self.after = after
def __call__(self, func):
def wrapper(wrapped_self, *a, **kw):
getattr(wrapped_self, self.before)()
result = func(self, *a, **kw)
getattr(wrapped_self, self.after)()
return result
return wrapper
class Example:
def _before(self):
print("before")
def _after(self):
print("after")
def say_done(self):
print("done")
@wrap()
def hello(self, name):
print("hi", name)
@wrap(after="say_done")
def goodbye(self, name):
print("goodbye", name)
Example().hello("Woj")
Example().goodbye("Woj")