简体   繁体   English

Python:用于字典的生成器和装饰器

[英]Python: Generators and decorators with for a dictionary

I created a problem that exercises a one's ability to use generators, decorators, and dictionaries in Python. 我创建了一个问题,该问题行使了一个人在Python中使用生成器,装饰器和字典的能力。

However, I cannot solve this exercise myself, and was wondering if it is at all possible to solve. 但是,我自己无法解决此问题,并且想知道是否有可能解决。

Is it possible to cache function output in the form of a dictionary using a decorator function that wraps a generator? 是否可以使用包装生成器的装饰器函数以字典的形式缓存函数输出?

The exercise is: 练习是:

Write a decorator to cache function invocation results. 编写装饰器以缓存函数调用结果。 Store pairs arg:result in a dictionary in an attribute of the function object. 将对arg:result存储在功能对象属性的字典中。 Generate these results using a generator function Test your code on the fibonacci function. 使用生成器函数生成这些结果。在fibonacci函数上测试代码。

I have attempted to implement it as follows: 我试图实现它如下:

def cachefunc(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return {func.__name__ + '(' + str(list(args))[1:-1] + ')' : str(result)}
    wrapper.__name__ = func.__name__
    wrapper.__doc__ = func.__doc__
    return wrapper

@cachefunc
def fibonacci(n):
    assert n >= 0
    if n < 2:
        return n
    else:
        return (fibonacci(n-1) + fibonacci(n-2))
def allfib():
    n = 0
    while True:
        yield fibonacci(n)
        n += 1

result = []
generator = allfib()
while len(result) < 10:
    x = next(generator)
    result.append(x)
print result

However, I get the following error: 但是,出现以下错误:

python dg.py
Traceback (most recent call last):
  File "dg.py", line 32, in <module>
    x = next(generator)
  File "dg.py", line 26, in allfib
    yield fibonacci(n)
  File "dg.py", line 10, in wrapper
    result = func(*args, **kwargs)
  File "dg.py", line 22, in fibonacci
    return (fibonacci(n-1) + fibonacci(n-2))
TypeError: unsupported operand type(s) for +: 'dict' and 'dict'

Does anybody know an alternative solution to a question like this? 有人知道这样的问题的替代解决方案吗?

Your Specific Error 您的具体错误

The error is here: 错误在这里:

return {func.__name__ + '(' + str(list(args))[1:-1] + ')' : str(result)}

You are returning a dictionary when you want to return result I believe. 我想返回结果时要返回字典。 I don't quite see where you are doing any cacheing actually inside cache function. 我不太了解您实际上在缓存功能中在哪里进行任何缓存。

General Comments 普通的留言

This pattern of cacheing is also commonly called memoization. 这种缓存模式通常也称为记忆。

Try this http://avinashv.net/2008/04/python-decorators-syntactic-sugar/ . 试试这个http://avinashv.net/2008/04/python-decorators-syntactic-sugar/ Scroll down to the portion about fibonacci. 向下滚动到有关斐波那契的部分。 The following code is found there: 在此找到以下代码:

class memoize:
  def __init__(self, function):
    self.function = function
    self.func_name = function.__name__
    self.memoized = {}

  def __call__(self, *args):
    try:
      print "Using Memo Solution for " + self.func_name + " on " + str(args)
      return self.memoized[args]
    except KeyError:
      print "Computing Solution Now for " + self.func_name + " on " + str(args)
      self.memoized[args] = self.function(*args)
    return self.memoized[args]

Then simply do: 然后只需执行以下操作:

@memoize
def fibonacci(n):
  assert n >= 0
  if n < 2:
    return n
  else:
    return (fibonacci(n-1) + fibonacci(n-2))

Full Code 完整代码

Memoization still works on the generator in your example, note the print statements show you that memoized results are being fetched. 在您的示例中,记忆仍然可以在生成器上进行,请注意,打印语句显示已获取记忆的结果。

class memoize:
  def __init__(self, function):
    self.function = function
    self.func_name = function.__name__
    self.memoized = {}

  def __call__(self, *args):
    try:
      print "Using Memo Solution for " + self.func_name + " on " + str(args)
      return self.memoized[args]
    except KeyError:
      print "Computing Solution Now for " + self.func_name + " on " + str(args)
      self.memoized[args] = self.function(*args)
    return self.memoized[args]

@memoize
def fibonacci(n):
  assert n >= 0
  if n < 2:
    return n
  else:
    return (fibonacci(n-1) + fibonacci(n-2))

def allfib():
  n = 0
  while True:
    yield fibonacci(n)
    n += 1

result = []
generator = allfib()
while len(result) < 10:
  x = next(generator)
  result.append(x)
print result

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM