我已经放弃了把一门课当作一袋我不想探究的虫子的记忆,下面是一个例子。我问的问题是“如何扩展或继承一个记忆类”,但很可能我犯了一个错误。下面的memoize类是brandizzi在How can I memoize a class instantiation in Python?中创建的一个类的精简版本,通过google这个主题可以找到更多相关的类。你知道吗
class memoize(object):
def __init__(self, cls):
self.cls = cls
# I didn't understand why this was needed
self.__dict__.update(cls.__dict__)
# bit about static methods not needed
def __call__(self, *args):
try:
self.cls.instances
except:
self.cls.instances = {}
key = '//'.join(map(str, args))
if key not in self.cls.instances:
self.cls.instances[key] = self.cls(*args)
return self.cls.instances[key]
class Foo():
def __init__(self,val):
self.val = val
def __repr__(self):
return "{}<{},{}>".format(self.__class__.__name__,self.val,id(self))
class Bar(Foo):
def __init__(self,val):
super().__init__(val)
f1,f2,f3 = [Foo(i) for i in (0,0,1)]
print([f1,f2,f3])
b1,b2,b3 = [Bar(i) for i in (0,0,1)]
print([b1,b2,b3])
# produces exactly what I expect
# [Foo<0,3071981964>, Foo<0,3071982092>, Foo<1,3071982316>]
# [Bar<0,3071983340>, Bar<0,3071983404>, Bar<1,3071983436>]
Foo = memoize(Foo)
f1,f2,f3 = [Foo(i) for i in (0,0,1)]
print([f1,f2,f3])
b1,b2,b3 = [Bar(i) for i in (0,0,1)]
print([b1,b2,b3])
# and now Foo has been memoized so Foo(0) always produces the same object
# [Foo<0,3071725804>, Foo<0,3071725804>, Foo<1,3071726060>]
# [Bar<0,3071711916>, Bar<0,3071711660>, Bar<1,3071725644>]
# this produces a compilation error that I don't understand
class Baz(Foo):
def __init__(self,val):
super().__init__(val)
# Traceback (most recent call last):
# File "/tmp/foo.py", line 49, in <module>
# class Baz(Foo):
# TypeError: __init__() takes 2 positional arguments but 4 were given
这个“配方”确实是一个非常糟糕的主意-一旦你将
Foo
重新绑定到memoize(Foo)
,Foo
就是一个memoize
实例,而不是类Foo
。这打破了wrt/python的type
和整个对象模型的所有期望。在本例中,我们将讨论class
语句的工作方式。实际上,这个:语法糖用于:
请注意,这种情况发生在运行时(与Python中除解析/字节码编译以外的所有内容一样,
type
是一个类,因此调用type
会创建一个新类,它是一个type
实例(这被称为“元类”—类的类,type
是默认的元类)。你知道吗因此,
Foo
现在是一个memoize
实例,而不是一个Type
实例,而且由于memoize
不是一个合适的元类(它的__init__
方法签名是不兼容的),整件事情就不能工作了。你知道吗要使其工作,您必须使
memoize
成为一个适当的元类(这是一个简化的示例,假设有一个名为param
的arg,但如果您愿意,可以对其进行泛化):相关问题 更多 >
编程相关推荐