3

Pythonのデコレータを作成したいのですが@pure、その一部として、関数のグローバル スコープへのアクセスを選択的に禁止することができます。

関数のグローバル/外部スコープとして機能する辞書をプログラムで変更する方法はありますか?

たとえば、次の例では、へのアクセスを傍受してfエラーhをスローできるようにしたいのですがg、純粋な関数であるため、へのアクセスを許可したいと考えています。

def f():
    print("Non-pure function")

@pure
def g(i):
    return i + 1

@pure
def h(i):
    f()
    return g(i)
4

1 に答える 1

5

古い関数オブジェクトから新しい関数オブジェクトを作成する必要があります。

newfunc = type(h)(h.__code__, cleaned_globals, h.__name__, h.__defaults__, h.__closure__)

ここでcleaned_globalsは、新しく作成された関数オブジェクトのグローバル名前空間として使用される辞書です。他のすべての引数は、元の関数のものをエコーし​​ます。

cleaned_globalsh.__globals__もちろん、のコピーに基づいている可能性があります。

デモ:

>>> def h(i):
...     f()
...     return g(i)
... 
>>> def g(i):
...     return i + 1
... 
>>> def f():
...     print("Non-pure function")
... 
>>> h(1)
Non-pure function
2
>>> cleaned_globals = {'g': g}
>>> newfunc = type(h)(h.__code__, cleaned_globals, h.__name__, h.__defaults__, h.__closure__)
>>> newfunc(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in h
NameError: global name 'f' is not defined
>>> cleaned_globals['f'] = lambda: print('Injected function')
>>> newfunc(1)
Injected function
2
于 2013-08-12T10:14:47.237 に答える