<p>关于你的问题,让我们看两点。</p>
<h2>使用备忘录</h2>
<p>您可以使用memoization,但是应该修饰<em>类</em>,而不是<code>__init__</code>方法。假设我们有一个回忆录:</p>
<pre><code>def get_id_tuple(f, args, kwargs, mark=object()):
"""
Some quick'n'dirty way to generate a unique key for an specific call.
"""
l = [id(f)]
for arg in args:
l.append(id(arg))
l.append(id(mark))
for k, v in kwargs:
l.append(k)
l.append(id(v))
return tuple(l)
_memoized = {}
def memoize(f):
"""
Some basic memoizer
"""
def memoized(*args, **kwargs):
key = get_id_tuple(f, args, kwargs)
if key not in _memoized:
_memoized[key] = f(*args, **kwargs)
return _memoized[key]
return memoized
</code></pre>
<p>现在你只需要装饰一下教室:</p>
<pre><code>@memoize
class Test(object):
def __init__(self, somevalue):
self.somevalue = somevalue
</code></pre>
<p>让我们看看测试?</p>
<pre><code>tests = [Test(1), Test(2), Test(3), Test(2), Test(4)]
for test in tests:
print test.somevalue, id(test)
</code></pre>
<p>输出如下。请注意,相同的参数产生的返回对象的id相同:</p>
<pre><code>1 3072319660
2 3072319692
3 3072319724
2 3072319692
4 3072319756
</code></pre>
<p>无论如何,我更愿意创建一个函数来生成对象并将其记住。对我来说似乎更干净,但可能是一些无关紧要的小毛病:</p>
<pre><code>class Test(object):
def __init__(self, somevalue):
self.somevalue = somevalue
@memoize
def get_test_from_value(somevalue):
return Test(somevalue)
</code></pre>
<h2>使用<code>__new__</code>:</h2>
<p>当然,也可以重写<code>__new__</code>。几天前我发布了<a href="https://stackoverflow.com/a/10789315/287976">an answer about the ins, outs and best practices of overriding ^{<cd2>}</a>这可能会有帮助。基本上,它说总是将<code>*args, **kwargs</code>传递给<code>__new__</code>方法。</p>
<p>例如,我更愿意记住一个创建对象的函数,或者甚至编写一个特定的函数,该函数负责从不将对象重新创建为同一个参数。当然,不过,这主要是我的意见,而不是规则。</p>