Python - 如何抽象通用 starting/ending 代码
Python - how to abstract common starting/ending code
我有一堆方法,看起来都像这样:
def myFunc():
...
{initialise stuff}
{do stuff}
{finalise stuff}
...
其中 {initialise stuff}
和 {finalise stuff}
对于每种方法 相同 ,并且 {do stuff}
可以使用 {initialise stuff}
中定义的变量。
为了避免重复,我想把{initialise stuff}
和{finalise stuff}
放在一个单独的方法中,可以从myFunc()
内部调用。所以,像这样:
def wrap(innerMethod):
vars = {initialise stuff}
innerMethod(vars)
{finalise stuff}
def myFunc():
...
wrap(lambda vars :
{do stuff}
)
...
不幸的是,Python 中似乎有 (除非最近 2 年才添加此功能)。因此,如果 {do stuff}
比单行长,这似乎不起作用。我可以将 {do stuff}
放入一个单独的方法中,但我不想这样做,因为:
{do stuff}
代码将永远不会被重复使用(每个方法都不同);
- 它使程序流程更混乱/更不合逻辑。
有没有其他方法把{initialise stuff}
和{finalise stuff}
放到一个单独的方法中?
您可以尝试 functools.wraps
和 decorator
:
import functools
def mywrapper(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
print("{initialize_stuff}")
result = f(*args, **kwargs)
print("{finalize_stuff}")
return result
return wrapper
@mywrapper
def myFunc():
print("{innerMethod}")
输出:
>>> myFunc()
{initialize_stuff}
{innerMethod}
{finalize_stuff}
Context managers 提供最佳解决方案 - 感谢@user2357112 的建议。
from contextlib import contextmanager
@contextmanager
def wrap():
{initialise stuff}
yield {stuff-to-return-to-method}
{finalise stuff}
def myFunc():
with wrap() as vars:
{do stuff}
您甚至可以将参数传递给 wrap
并在初始化中使用它们。
如果你想要 {finalise stuff}
到 运行 即使包装代码抛出异常(你通常希望使用上下文管理器),你应该将 yield
包装在 try
并将定稿放在 finally
:
@contextmanager
def wrap():
{initialise stuff}
try:
yield {stuff-to-return-to-method}
finally:
{finalise stuff}
我有一堆方法,看起来都像这样:
def myFunc():
...
{initialise stuff}
{do stuff}
{finalise stuff}
...
其中 {initialise stuff}
和 {finalise stuff}
对于每种方法 相同 ,并且 {do stuff}
可以使用 {initialise stuff}
中定义的变量。
为了避免重复,我想把{initialise stuff}
和{finalise stuff}
放在一个单独的方法中,可以从myFunc()
内部调用。所以,像这样:
def wrap(innerMethod):
vars = {initialise stuff}
innerMethod(vars)
{finalise stuff}
def myFunc():
...
wrap(lambda vars :
{do stuff}
)
...
不幸的是,Python 中似乎有 {do stuff}
比单行长,这似乎不起作用。我可以将 {do stuff}
放入一个单独的方法中,但我不想这样做,因为:
{do stuff}
代码将永远不会被重复使用(每个方法都不同);- 它使程序流程更混乱/更不合逻辑。
有没有其他方法把{initialise stuff}
和{finalise stuff}
放到一个单独的方法中?
您可以尝试 functools.wraps
和 decorator
:
import functools
def mywrapper(f):
@functools.wraps(f)
def wrapper(*args, **kwargs):
print("{initialize_stuff}")
result = f(*args, **kwargs)
print("{finalize_stuff}")
return result
return wrapper
@mywrapper
def myFunc():
print("{innerMethod}")
输出:
>>> myFunc()
{initialize_stuff}
{innerMethod}
{finalize_stuff}
Context managers 提供最佳解决方案 - 感谢@user2357112 的建议。
from contextlib import contextmanager
@contextmanager
def wrap():
{initialise stuff}
yield {stuff-to-return-to-method}
{finalise stuff}
def myFunc():
with wrap() as vars:
{do stuff}
您甚至可以将参数传递给 wrap
并在初始化中使用它们。
如果你想要 {finalise stuff}
到 运行 即使包装代码抛出异常(你通常希望使用上下文管理器),你应该将 yield
包装在 try
并将定稿放在 finally
:
@contextmanager
def wrap():
{initialise stuff}
try:
yield {stuff-to-return-to-method}
finally:
{finalise stuff}