为什么在这种情况下 isinstance() return False?
Why does isinstance() return False in this case?
我想编写一个允许记忆构造函数的装饰器。当我构造一个 class 时,我希望尽可能从缓存中 returned 对象。
以下代码改编自here。
from functools import wraps
def cachedClass(klass):
cache = {}
@wraps(klass, updated=())
class wrapper:
def __new__(cls, *args, **kwargs):
key = (cls,) + args + tuple(kwargs.items())
try:
inst = cache.get(key, None)
except TypeError:
# Can't cache this set of arguments
inst = key = None
if inst is None:
inst = klass.__new__(klass, *args, **kwargs)
inst.__init__(*args, **kwargs)
if key is not None:
cache[key] = inst
return inst
return wrapper
一个小型测试套件重新验证了以下内容:
>>> @cachedClass
... class Foo:
... pass
>>> f1 = Foo()
>>> f2 = Foo()
>>> f1 is f2
True
>>> Foo
<class 'cache.Foo'>
>>> type(f1)
<class 'cache.Foo'>
>>> isinstance(f1, Foo)
False
我预计最后一个表达式会 return True
。我错过了什么?
@cachedClass
class Foo:
pass
在语义上等同于
class Foo:
pass
Foo = cachedClass(Foo)
Foo
名称被分配了 cachedClass
的 return 值,这是
wrapper
class.
wrapper
又被 functool.wraps
修饰,它复制了 Foo
的 __name__
属性以及一些其他的 dunder 属性,所以 wrapper
class 看起来 像 Foo
.
如果删除 @wraps
行并打印
print(type(f1), Foo, type(f1) is Foo, sep=', ')
你会看到 f1
是原始 Foo
class 的实例,但是 Foo
name 现在指的是 wrapper
class,它们是不同的对象:
<class '__main__.Foo'>, <class '__main__.cachedClass.<locals>.wrapper'>, False
我想编写一个允许记忆构造函数的装饰器。当我构造一个 class 时,我希望尽可能从缓存中 returned 对象。
以下代码改编自here。
from functools import wraps
def cachedClass(klass):
cache = {}
@wraps(klass, updated=())
class wrapper:
def __new__(cls, *args, **kwargs):
key = (cls,) + args + tuple(kwargs.items())
try:
inst = cache.get(key, None)
except TypeError:
# Can't cache this set of arguments
inst = key = None
if inst is None:
inst = klass.__new__(klass, *args, **kwargs)
inst.__init__(*args, **kwargs)
if key is not None:
cache[key] = inst
return inst
return wrapper
一个小型测试套件重新验证了以下内容:
>>> @cachedClass
... class Foo:
... pass
>>> f1 = Foo()
>>> f2 = Foo()
>>> f1 is f2
True
>>> Foo
<class 'cache.Foo'>
>>> type(f1)
<class 'cache.Foo'>
>>> isinstance(f1, Foo)
False
我预计最后一个表达式会 return True
。我错过了什么?
@cachedClass
class Foo:
pass
在语义上等同于
class Foo:
pass
Foo = cachedClass(Foo)
Foo
名称被分配了 cachedClass
的 return 值,这是
wrapper
class.
wrapper
又被 functool.wraps
修饰,它复制了 Foo
的 __name__
属性以及一些其他的 dunder 属性,所以 wrapper
class 看起来 像 Foo
.
如果删除 @wraps
行并打印
print(type(f1), Foo, type(f1) is Foo, sep=', ')
你会看到 f1
是原始 Foo
class 的实例,但是 Foo
name 现在指的是 wrapper
class,它们是不同的对象:
<class '__main__.Foo'>, <class '__main__.cachedClass.<locals>.wrapper'>, False