首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python回忆录装饰师

Python回忆录装饰师
EN

Code Review用户
提问于 2012-02-29 07:54:20
回答 2查看 1.2K关注 0票数 2

我花了一整晚的时间来制作这个食谱。这是我的第一个Python装饰师。我觉得我现在对装饰师的工作方式有了充分的理解,我想我想出了一个很好的面向对象的算法来自动提供回忆录。请告诉我你的想法。

粘贴在这里后,我做了一些快速的更改,所以如果我的更改损坏了什么,请告诉我(手边没有解释器)。

代码语言:javascript
复制
"""This provides a way of automatically memoizing a function. Using this eliminates the need for extra code. Below is an example of how it would be used on a recursive Fibonacci sequence function:

    def fib(n):
        if n in (0, 1): return n
        return fib(n - 1) + fib(n - 2)

    fib = memoize(fib)

That's all there is to it. That is nearly identical to the following:

    _memos = {}
    def fib(n):
        if n in _memos:
            return _memos[n]
        if n in (0, 1):
            _memos[n] = n
            return _memos[n]
        _memos[n] = fib(n - 1) + fib(n - 2)
        return _memos[n]

The above is much more difficult to read than the first method. To make things even simpler, one can use the memoize function as a decorator like so:

    @memoize
    def fib(n):
        if n in (0, 1): return n
        return fib(n - 1) + fib(n - 2)

Both the first and third solutions are completely identical. However, the latter is recommended due to its elegance. Also, note that functions using keywords will purposely not work. This is because this memoization algorithm does not store keywords with the memos as it HEAVILY increases the CPU load. If you still want this functionality, please implement it at your own risk."""
class memoize:

    """Gives the class it's core functionality."""
    def __call__(self, *args):
        if args not in self._memos:
            self._memos[args] = self._function(*args)
        return self._memos[args]

    def __init__(self, function):
        self._memos = {}
        self._function = function

    # Please don't ask me to implement a get_memo(*args) function.

    """Indicated the existence of a particular memo given specific arguments."""
    def has_memo(self, *args):
        return args in self._memos

    """Returns a dictionary of all the memos."""
    @property
    def memos(self):
        return self._memos.copy()

    """Remove a particular memo given specific arguments. This is particularly useful if the particular memo is no longer correct."""
    def remove_memo(self, *args):
        del self._memos[args]

    """Removes all memos. This is particularly useful if something that affects the output has changed."""
    def remove_memos(self):
        self._memos.clear()

    """Set a particular memo. This is particularly useful to eliminate double-checking of base cases. Beware, think twice before using this."""
    def set_memo(self, args, value):
        self._memos[args] = value

    """Set multiple memos. This is particular useful to eliminate double-checking of base cases. Beware, think twice before using this."""
    def set_memos(self, map_of_memos):
        self._memos.update(map_of_memos)
EN

回答 2

Code Review用户

回答已采纳

发布于 2012-03-01 11:47:28

首先想到的是查看代码:样式。

将文档字符串置于函数之上而不是下面有一个特殊的原因?您所做的方式将在None属性中显示__doc__

IMHO中的一些字符串甚至不是doc-string:

def __call__(self,*args)“”使类具有其核心功能。

这并不能说明什么。还请记住,注释是给程序员的,docstring是给用户的。

  • PEP8告诉你所有关于这个样式指南的事情,
  • PEP257是专门关于Docstring约定的。

而且,我不太喜欢您将__call__方法放在__init__之前,但我不知道这是我自己,还是有一些约定。

澄清了这一点,我未能在您的所有方法中创建除__init____call__之外的所有方法。他们有什么用?你的代码在哪里使用它们?

如果你需要什么东西,那就不要写代码,否则你就会写一些你不需要的东西,这可能不符合你对明天的假设要求。

我知道您可能在做一个关于装饰师的练习,但是在实现某些东西时,不要仅仅为了它而编写代码。

让我们更深入地了解一下您的非文档字符串,如以下所示:

“删除所有备忘录。如果影响输出的内容发生了变化,这尤其有用。”def remove_memos(self):self._memos.clear()

这大概应该是:

代码语言:javascript
复制
def remove_memos(self):
    """Removes all memos."""
    self._memos.clear()

仅此而已。究竟做了什么“如果影响产出的东西发生了变化,这就特别有用。”这意味着?“影响输出的东西已经改变了”?这一切都很奇怪和混乱。另外,你的装饰师如何知道“影响输出的东西已经改变了”?

这里什么都没有:

def __call__(self,* args ):如果args不在self._memos中: self._memos参数 = self._function(*args)返回self._memos参数

这样做或使用任何其他方法。而且,您似乎无法提供可能使用它们的场景(即使可以,也无法使用它们)。

我的观点是,所有这些额外的方法都是无用的,如果您学习了一些Python,可能并不是编写它们,但这就是它们的使用范围内的问题。

票数 3
EN

Code Review用户

发布于 2012-02-29 08:28:07

代码语言:javascript
复制
"""Gives the class it's core functionality."""
def __call__(self, *args):
    if args not in self._memos:
        self._memos[args] = self._function(*args)
    return self._memos[args]

“请求原谅而不是请求许可”更惯用(也更快),例如:

代码语言:javascript
复制
def __call__(self, *args):
    try:
        return self._memos[args]
    except KeyError:
        value = self._function(*args)
        self._memos[args] = value
        return value
票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/9538

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档