2013-05-01 27 views
1

這個問題是不是我的代碼
我只是想要求的原因,我需要function.func_name有什麼辦法可以懶評估function.func_name?


懶評價;我使用的是curry裝飾在我的代碼
我把它展現令行禁止通過修改FUNC_NAME
參數,以便當我需要一些調試,我可以很容易地找出哪些參數已經令行禁止

>> My modified version <<
curry>> The original version <<

例子:

@curry 
def f(a, b, c, flag_foo=True, flag_bar=False): 
    pass 

>>> f 
<function f at 0x100545398> 

>>> f(1, flag_bar=True) 
<function f(1, flag_bar=True) at 0x1005451b8> 

>>> f(1, flag_bar=True)(3, flag_foo=False) 
<function f(1, 3, flag_foo=False, flag_bar=True) at 0x1004aee60> 

由於func_name永遠無需調試訪問,
我想避免FUNC_NAME的評價;開銷

然而,function是不能被分類的最後一個類
有什麼辦法可以執行懶惰評價function.func_name

任何建議,歡迎

+2

我相信在這個複雜的情況簡直是更好地使'curry'一個類,並用自己的對象替換功能'__str__'和'__repr__'完成你想要的功能。這也允許任何懶惰的評估,因爲你可以使用諸如屬性/ getters之類的東西。 – Bakuriu 2013-05-01 16:15:39

+1

我已經嘗試過各種黑客攻擊,並且它看起來並不像在Python中實現這個功能對象一樣可能,儘管您可能可以使用擴展模塊來做到這一點。但是,我會推薦@Bakuriu的建議。如果你在一個類上定義了一個'__call__'方法,那麼你可以像使用一個函數一樣使用一個實例。 – Aya 2013-05-01 16:20:32

+2

你有理由認爲這是一個瓶頸嗎?解決方案將非常複雜,所以我認爲這不值得。 – delnan 2013-05-01 16:26:16

回答

1

代碼:

class Curried(object): 
    def __init__(self, func, args=None, kwargs=None): 
     self._func = func 
     self._args =() if args is None else args[:] 
     self._kwargs = {} if kwargs is None else dict(kwargs) 
     self._name = None 

    def __call__(self, *args, **kwargs): 
     if args or kwargs: 
      return Curried(self._func, 
          self._args + args, 
          dict(self._kwargs.items() + kwargs.items())) 
     else: 
      return self._func(*self._args, **self._kwargs) 

    def __str__(self): 
     if self._name is None: 
      self._name = self._get_curried_name() 
     return self._name 

    def _get_curried_name(self): 
     _args = ([str(a) for a in self._args] + 
       ['{}={}'.format(k, v) for k, v in self._kwargs.iteritems()]) 
     all_args = ", ".join(_args) 
     return '<curried {}({}) at 0x{:x}>'.format(
      self._func.func_name, all_args, id(self)) 

    def curry(func): 
     _curried = Curried(func) 
     return _curried 

測試:

@curry 
def f(a, b, c, flag_foo=True, flag_bar=False): 
    return 'horray!' 

print f 
print f(1, 2, flag_bar=True) 
print f(1, 2, flag_bar=True)(3, flag_foo=False) 
print f(1, 2, flag_bar=True)(3, flag_foo=False)() 

而結果:

<curried f() at 0x100484210> 
<curried f(1, 2, flag_bar=True) at 0x100484250> 
<curried f(1, 2, 3, flag_bar=True, flag_foo=False) at 0x100484310> 
horray! 

取而代之的是 「純」 的功能,在這裏你會得到一個callab作爲功​​能的le類。你只評估一次這個名字。當然,如果你想func_name您可以添加這樣的變量爲property,並返回str(self)這是一次評估

+0

是的,'__call__'是執行此操作的唯一方法。 '_kwags'看起來像一個錯字。謝謝! – zhangyoufu 2013-05-01 17:32:00