懒惰地用Python定义函数

时间:2016-12-28 19:13:50

标签: python monkeypatching inspect

这更像是一个理论而非实际的问题。在Python中,我们可以做到这个非常丑陋的事情:

import inspect
import re


class A(object):
  def __init__(self, *args, **kwargs):
    super(A, self).__init__(*args, **kwargs)
    self._name_cache = {}
    # Still want to be able to do proper lookups.
    self._old_get = self.__getattr__

  def __getattr__(self, n, *args, **kwargs):
    # Gets the name of the most local reference.
    frame = inspect.currentframe().f_back
    tmp = frame.f_locals.items() + frame.f_globals.items()
    for k, var in tmp.items():
      if isinstance(var, self.__class__):
        if var is self:
          name = k
          break
        else:
         assert 'Life' == 'Bad'
    patt = re.compile(r'^add_(\d+)$')
    if patt.search(n):
      # Add to the cached functions and return new "attribute."
      if n not in self._name_cache:
          exec('def %s(n):\n  return %s + n' % (n, patt.sub(r'\1', n)))
          exec('%s._name_cache["%s"] = %s' % (name, n, n))
          exec('print "Is it there? %s"' % str(n in self._name_cache))
        return self._name_cache[n]
      else:
        return self._old_get(n, *args, **kwargs)


a = A()
print a.add_2(3)  # Prints 5

使用元类可能有一个更清晰的解决方案,但我不确定我是否能够鞭打它。无论如何,我们做了一些看起来像语法上懒惰,即时成员函数生成的东西。

我有两个问题:

  1. 我现在想知道是否有办法在全球范围内实现这一目标。我只是修补inspect.current_frame().f_globals的{​​{1}}方法,但它的属性是只读的。是否有解释器可写函数来管理顶级get() ed函数的查找?

  2. 使用def模块可以做些什么其他堕落的事情?

0 个答案:

没有答案