Ark*_*nez 5 python metaprogramming function
我正在编写一个提供一个函数并需要初始化步骤的模块,但是由于我需要在第一次调用时初始化的某些限制,所以我在python中寻找适当的习惯用法,这将允许我摆脱条件.
#with conditional
module.py
initialized = False
def function(*args):
if not initialized: initialize()
do_the_thing(*args)
Run Code Online (Sandbox Code Playgroud)
我想用这样的东西摆脱那种条件(它不起作用):
#with no conditional
module.py
def function(*args):
initialize()
do_the_thing(*args)
function = do_the_thing
Run Code Online (Sandbox Code Playgroud)
我意识到我不能只在模块中使用名称并在运行时更改它们,因为使用的模块from module import function永远不会受到function=other_fun模块内部的影响.
那么,有没有任何pythonic成语可以正确的方式做到这一点?
没什么特别的方式(我在这里发布的方法,这可能是最好的方法):
module.py:
def initialize():
print('initialize')
def do_the_thing(args):
print('doing things',args)
def function(args):
_function(args)
def firsttime(args):
global _function
initialize()
do_the_thing(args)
_function=do_the_thing
_function=firsttime
Run Code Online (Sandbox Code Playgroud)
这个想法很简单:你只需添加一个间接层.function总是打电话_function,但_function先点到firsttime,然后永远点到do_the_thing.
test.py:
from module import function
function(1)
function([2,3])
Run Code Online (Sandbox Code Playgroud)
运行test.py产生
initialize
('doing things', 1)
('doing things', [2, 3])
Run Code Online (Sandbox Code Playgroud)
我的第一个想法是使用一个生成器,但是,正如Triptych指出的那样,如果使用生成器,则无法将args传递给函数.所以...
这是一种使用协程的方法(与生成器不同,它允许您发送args以及从协程接收值):
module.py:
def coroutine(func):
# http://www.dabeaz.com/coroutines/index.html
def start(*args,**kwargs):
cr = func(*args,**kwargs)
cr.next()
return cr
return start
def initialize():
print('initialize')
def do_the_thing(*args, **kwargs):
print('doing things', args, kwargs)
return ('result', args)
@coroutine
def _function():
args, kwargs = (yield)
initialize()
while True:
args, kwargs = (yield do_the_thing(*args, **kwargs))
_function = _function().send
def function(*args, **kwargs):
# This is purely to overcome the limitation that send can only accept 1 argument
return _function((args,kwargs))
Run Code Online (Sandbox Code Playgroud)
运行
print(function(1, x = 2))
print(function([2, 3]))
Run Code Online (Sandbox Code Playgroud)
产量
initialize
('doing things', (1,), {'x': 2})
('result', (1,))
('doing things', ([2, 3],), {})
('result', ([2, 3],))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
204 次 |
| 最近记录: |