デコレータを使用して関数を実行すると、デコレータ呼び出しを呼び出さずに関数を実行することができますか?デコレータをオプションでオンまたはオフにする方法
与えられた関数foo
は、オプションでデコレータをオンまたはオフにできますか?
@decorator
def foo():
//do_somthing
考える
はそれがオフになってdecorator
で可能な走行foo
ですか?
デコレータの有無にかかわらず実行したい場合があります。たとえば、効率的なキャッシングが必要なため、良い方法ではないので、factorial(n)
関数でデコレータベースのキャッシングをオフにします。
私の質問はこの質問Optionally use decorators on class methodsと似ています。デコレータ切り替えのON/OFF(apiとして公開)の良いアプリケーションについて説明します。
私は機能を使用していた場合、goo
言うとデコレータの有無にかかわらずgoo
を実行するのいずれかのオプションを与えるが、私は次のような機能を切り替えるオン/オフこのオプションのデコレータを達成するための原始的な、ハックの方法を試してみました:
# this is the decorator class that executes the function `goo`
class deco(object):
def __init__(self, attr):
print "I am initialized"
self.fn = None
# some args you may wana pass
self.attr = attr
# lets say you want these attributes to persist
self.cid = self.attr['cid']
self.vid = 0
def __call__(self, f):
# the call executes and returns another inner wrapper
def wrap(*args):
# this executes main function - see closure
self.fn = f
self.vid = args[0]
self.closure(*args)
return wrap
def closure(self, *args):
n = args[0]
self.cid[n] = self.vid
#goo = deco(fn, attr)
print 'n',n
# executes function `goo`
self.fn(*args)
class gooClass(object):
class that instantias and wraps `goo`around
def __init__(self, attr, deco):
'''
@param:
- attr: some mutable data structure
- deco: True or False. Whether to run decorator or not
'''
self.attr = attr
self.deco = deco
def __call__(self, *args):
if self.deco:
# initiate deco class with passed args
foo = deco(self.attr)
# now pass the `goo` function to the wrapper inside foo.__class__.__call__
foo = foo(self.goo)
return foo(*args)
else:
# execute w/o decorator
return self.goo(*args)
def goo(self, n):
# recursive goo
if n>0:
print 'in goo',n
#print n
# to recurse, I recreate the whole scene starting with the class
# because of this the args in `deco` Class init never persist
too = gooClass(self.attr, self.deco)
return too(n-1)
else: return n
def Fn(n, decoBool):
# this function is where to start running from
attr = {}
cid = [0]*(n+1)
attr['cid'] = cid
#following wud work too but defeat the purpose - have to define again! foo is goo actually
#@deco(attr)
#def foo(n):
# if n>0:
# print 'in foo',n
# #print n
# return foo(n-1)
# else: return n
#return foo(n), attr
# create the gooClass and execute `goo` method instance
foo = gooClass(attr, decoBool)
print foo(n)
return foo
res = Fn(5, True)
print res.attr
print "="*10
res = Fn(5, False)
print res.attr
出力:
I am initialized
n 5
in goo 5
I am initialized
n 4
in goo 4
I am initialized
n 3
in goo 3
I am initialized
n 2
in goo 2
I am initialized
n 1
in goo 1
I am initialized
n 0
None
{'cid': [0, 1, 2, 3, 4, 5]}
==========
in goo 5
in goo 4
in goo 3
in goo 2
in goo 1
0
{'cid': [0, 0, 0, 0, 0, 0]}
を技術的に動作しますが、私はそれがブートストラップハックだと思うています。ピジョンソニックではありません。 新しいクラスが再帰的に作成されるたびに。
質問があり、私はこれを作成したので、関連する回答を見つけることができませんでした。オプションでデコレータをオン/オフする方法はありますか?
ヒント:レビューアがあなたの変更のコメントを参照してください、あなたは幼稚園児があなたの質問を再開するためにそれらをやる気にさせる良い方法ではないようにコミュニティにダウン話す必要が暗示しています。また、実行時にデコレーションをオフにするメカニズムを使用することを受け入れるでしょうか?デコレータにdebugFlagが有効になっているかどうか調べます。有効になっていなければ、デコレータ関数をダミーのラッパーに置き換えます。これは少しオーバーヘッドがありますが、もっとエキゾチックなものを考え出すのには十分ではありません(しかし、私はただ一つのデコレータと多くはありません)。 – Foon
@Foon私たちは皆、お互いを助けようとしています。利益。私が複雑な/厄介な状況を作り、それを幼稚園レベルにダムすることができれば、私は事を説明する上で素晴らしい仕事をしたと思います。 。この質問が表示されるたびに、私はそれをあまりにも愚かにしようとします。それがあなたにとって理にかなっているなら、この視点を試してみてください。将来的には、勤勉で尊敬できるコミュニティを馬鹿げた印象を持たないことを願っています。 はい、私はすべての入力/改善を受け入れます。 'decoBool'と' deco'をチェックしてください - 私のコードではあなたのdebugFlagですか? – user2290820
私はヘルパーのドキュメント/コメントをコードに追加しようとします。それは助けになるだろうが、ここでは夜遅すぎる。私は明日それをします。 – user2290820