制作“isinstance”与装饰者合作
Python 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
的行为几乎就像一个 mixin,只不过混合在这里不合适。有什么办法可以让上面的代码工作吗?我还应该注意到 isinstance
行还给出了以下错误:
isinstance(f, Foo)
TypeError: isinstance() arg 2 必须是类型或类型元组
How does the Python isinstance
function work internally? Is there anything I can do to alter its results, like define a special function inside a class or something? Here's my use case:
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
acts almost like a mixin, except a mixing wouldn't be appropriate here. Is there any way I can make the above code work? I should also note that the isinstance
line also gives the following error:
isinstance(f, Foo)
TypeError: isinstance() arg 2 must be a type or tuple of types
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
下面的怎么样:
使用上面的代码:
isinstance(f, Foo)
可以工作;f()
调用装饰方法,然后转发到原始方法。基本思想是确保被装饰的
Foo
仍然是一个类,并且还要确保被装饰的Foo
是以下类的子类原来的Foo
。PS 我并不完全清楚这一切的目的;元类可能是实现您想要做的事情的更好方法。
How about the following:
With the above code:
isinstance(f, Foo)
works;f()
calls the decorated method which then forwards to the original method.The basic idea is to make sure that the decorated
Foo
is still a class, and to also make sure that the decoratedFoo
is a subclass of the originalFoo
.P.S. The purpose of all this is not entirely clear to me; it might be that metaclasses are a better way to achieve what you're trying to do.
问题是您的示例中的 Foo 不是一个类。
此代码:
相当于:
这意味着
Foo
是类Decorator
的实例。因为 Foo 不是类或类型,所以 isinstance 会抱怨。The problem is that
Foo
in your example isn't a class.This code:
is equivalent to:
Which means that
Foo
is an instance of classDecorator
. BecauseFoo
is not a clas or type,isinstance
complains.当修饰一个类时,将修饰的返回值也设置为类型通常是有用的或可取的;实现此目的最明显的方法是让装饰器构造并直接返回一个新类。
该功能已经由元类处理;事实上,元类比装饰器更强大,因为您可以在构造装饰类之前描述新类。
另一种选择是返回传入的同一对象;但有一些变化。这对装饰器来说是更好的用途,因为当您嵌套装饰器时它效果很好。由于您要修改使用
Foo()
时的行为,因此您可能需要修改 Foo 的__init__
,它可能如下所示:When decorating a class, it's often useful or desirable to for the decorated return value to also be type; The most obvious way of achieving this is to have the decorator construct and return a new class directly.
That functionality is already handled by metaclasses; In fact, metaclasses are a bit more powerful than decorators, since you get to describe the new class before a decorated class has even been constructed.
Another option is to return the same object that was passed in; but with some changes. That's a better use for decorators, since it works well when you nest decorators. Since you're modifying the behavior when
Foo()
is used, then you probably want to modify Foo's__init__
, which might look like this:如果不调用
Foo
,则无法获取Foo
返回的对象的类型。isinstance
抱怨它的第二个参数,因为它是一个实例 - 在你的例子中是Decolated
的实例。虽然您将 Foo 视为一个类,但实际上它只是一个可调用对象,而不是一个类。也许接下来会帮助您重新思考/解决您的问题:
You can't get type of the object that
Foo
returns without callingFoo
.isinstance
complains about its second argument because it is an instance - in you case instance ofDecorated
. Although you think ofFoo
like a class but actually it is just a callable object and it is not a class.Maybe the next will help you to rethink/solve your problem: