Python 制作';iInstance';与装饰师合作
PythonPython 制作';iInstance';与装饰师合作,python,decorator,isinstance,Python,Decorator,Isinstance,Pythonisinstance函数如何在内部工作?我可以做些什么来改变它的结果,比如在类中定义一个特殊的函数或者其他什么?以下是我的用例: class Decorator: def __init__(self, decorated): self._decorated = decorated def __call__(self): return self._decorated() @Decorator class Foo: pass
isinstance
函数如何在内部工作?我可以做些什么来改变它的结果,比如在类中定义一个特殊的函数或者其他什么?以下是我的用例:
class Decorator:
def __init__(self, decorated):
self._decorated = decorated
def __call__(self):
return self._decorated()
@Decorator
class Foo:
pass
f = Foo()
# How can I make this be true?
isinstance(f, Foo)
Decorator
的行为几乎像一个混音器,只是混音器在这里并不合适。有什么方法可以让上面的代码工作吗?我还应该注意,isinstance
行也给出了以下错误:
isinstance(f,Foo)TypeError:isinstance()arg 2必须是类型或类型的元组
那么以下内容如何:
def Decorator(decorated):
class Dec(decorated):
def __call__(self):
print 'in decorated __call__'
return decorated.__call__(self)
return Dec
@Decorator
class Foo(object):
def __call__(self):
print 'in original __call__'
f = Foo()
# How can I make this be true?
print isinstance(f, Foo)
使用上述代码:
works李>isinstance(f,Foo)
f()
Foo
仍然是一个类,并且还确保修饰的Foo
是原始Foo
的子类
另外,我并不完全清楚这一切的目的;元类可能是实现您想要做的事情的更好方法。问题在于您的示例中的
Foo
不是类
此代码:
@Decorator
class Foo:
pass
相当于:
class Foo:
pass
Foo = Decorator(Foo)
这意味着
Foo
是类Decorator
的实例。因为Foo
不是clas或类型,isinstance
会抱怨。如果不调用Foo
就无法获取Foo
返回的对象类型
isinstance
抱怨它的第二个参数,因为它是一个实例,在您的例子中是修饰的实例。虽然您认为Foo
像一个类,但实际上它只是一个可调用的对象,而不是一个类
也许下一步将帮助您重新思考/解决您的问题:
>>> isinstance(f, Foo._decorated)
True
在装饰类时,装饰后的返回值也是类型通常是有用的或可取的;实现这一点最明显的方法是让decorator构造并直接返回一个新类 该功能已经由元类处理;事实上,元类比装饰器更强大,因为在构建装饰类之前,您就可以描述新类了 另一个选项是返回传入的相同对象;但是有一些变化。这对于装饰者来说是一个更好的用途,因为当你嵌套装饰者时,它工作得很好。由于您在使用
Foo()
时正在修改行为,因此您可能需要修改Foo的\uuuu init\uuuu
,它可能如下所示:
>>> def Decorator(cls):
... assert isinstance(cls, type)
... try:
... old_init = cls.__init__.im_func
... except AttributeError:
... def old_init(self): pass
... def new_init(self):
... # do some clever stuff:
... old_init(self)
... cls.__init__ = new_init
... return cls
...
>>> @Decorator
... class Foo(object):
... def __init__(self): pass
...
>>> @Decorator
... class Bar(object):
... pass
...
>>> f = Foo()
>>> isinstance(f, Foo)
True
你到底想用这个做什么?你还没有告诉我们你的装饰师是做什么的,所以很难知道什么会起作用。考虑用装饰器来改变类本身的属性,然后返回类,或者用元元组来代替类,而不是修饰器。这只解决了他的“应该注意”,它没有告诉他如何使IS实例工作。