2012-03-27 4 views
0

基本的には、Foo()クラスにいくつかのFoo.bar(arg1、name)メソッドを提供するAPIがあります。私は猿のパッチよりも、この他のためのよりエレガントな方法があるのか​​疑問に思っコンテキストマネージャ内での関数の部分的な適用( "with ..")

x=Foo() 
with my_argument(name="Something") as e: 
    x.bar(arg1=5) # == x.bar(arg1=5, name="Something") in this context 

このようなつまりコンテキストマネージャ、内Foo.barにfunctools.partialオブジェクトを適用する方法はありますFoo.bar?

編集:ポイントがある 、私はこのようなコードを持っている:

with Arguments(name="constraint"): 
    model.addConstr(a) 
    model.addConstr(b) 
+2

一部のアプリケーションを意味します。部分的な評価は(通常は静的で、部分的には高価なため)[プログラム変換](http://morepypy.blogspot.com/2012/01/comparing-partial-evaluation-and.html)です。これがおそらくあなたが本当にそれをしたくないのであれば、コンテキストマネージャーを提供したオブジェクトのメソッドに限定されているかもしれません。 – delnan

+0

そうではありませんが、そうです。 –

答えて

1

model.addConstr(a, name="constraint_1") 
model.addConstr(b, name="constraint_2") 

、次のコードは、同じ呼び出しへの 'モデル' を得なければならない追加的な決まり文句なし

そうではありません。あなたの my_argumentクラスは、それを渡さずに x.barで動作することを意図していることをどのように知っていますか?この場合、 __enter__()__exit__()の方法は my_argumentと正確に何が行われますか?

x.barのオブジェクトをfunctools.partialにして、それを使用するだけの理由がわかりません。

私はあなたが必ずしもあなたの代わりにfunctoolsから部分を使用することができ、コンテキストマネージャを必要とは思わない
2

from functools import partial 
x=Foo() 
_xbar = partial(x.bar, name="something") 
_xbar(arg1=5) 

は、あなたが "スイッチ文脈" したい場合は、単にredifine _xbar

_xbar = partial(x.bar, name="some other thing") 
2
class Argumentor(object): 
    def __init__(self, *args, **kwargs): 
    self.args = args 
    self.kwargs = kwargs 

    def __enter__(self): 
    return self 

    def __exit__(self, exc_type, exc_val, exc_tb): 
    pass 

    def __call__(self, func, *args, **kwargs): 
    newargs = args + self.args 
    newkwargs = kwargs.copy() 
    newkwargs.update(self.kwargs) 
    return func(*newargs, **newkwargs) 

def foo(num, name): 
    print num, name 

with Argumentor(name='bar') as f: 
    f(foo, 42) 
+0

うまくやった!そういうことは考えていないでしょう。 – brice

+0

これをマネージャのinitへの引数として渡すか、またはマネージャ自身が部分的に適用された呼び出し可能関数を返すようにするのは、それほどうれしくありませんか? – Marcin

+0

@Marcin:それを複数の機能に適用したいのですが? –

関連する問題