是否有可能将我自己的装饰器应用于Python中的内置方法?(Is it possible to apply my own decorators to builtin methods in Python

编程入门 行业动态 更新时间:2024-10-26 14:40:05
是否有可能将我自己的装饰器应用于Python中的内置方法?(Is it possible to apply my own decorators to builtin methods in Python?)

我刚刚遇到了Python装饰器。 只是出于兴趣,您可以以某种方式将自己的装饰器应用于内置对象方法吗? 说我想申请这个:

def remove_empty(fn): def filtered(): return filter(lambda x: x != '', fn()) return filtered

为此:

some_string.split('\n')

为了删除空的字符串。 可能吗? 甚至是一个好主意?

I've just come across Python decorators. Just out of interest, can you apply your own decorator to a built-in object method somehow? Say I wanted to apply this:

def remove_empty(fn): def filtered(): return filter(lambda x: x != '', fn()) return filtered

To this:

some_string.split('\n')

in order to remove empty strings. Is it possible? Or even a good idea?

最满意答案

这是可能的; 这取决于你的意思。 这样的装饰语法...

@dec def foo(): pass

真的只是糖:

def foo(): pass foo = dec(foo)

因此,没有什么可以阻止您在全局命名空间中的预定义函数上使用装饰器。

func = dec(func)

但是内置类的方法存在于该类的名称空间中,并且该名称空间不能直接修改,正如chepner已经指出的那样。 这是一件好事,因为它可以确保str类型的对象将按预期行事! 但是,您可以继承 str并装饰该方法。 (以下是Python 2中的工作;在Python 3中,将filter的输出传递给列表, super也可能有点不同;我将来会发布Python 3更新。)

>>> def remove_empty(fn): ... def filtered(*args, **kwargs): ... return filter(lambda x: x != '', fn(*args, **kwargs)) ... return filtered ... >>> class WeirdString(str): ... @remove_empty ... def split(self, *args, **kwargs): ... return super(WeirdString, self).split(*args, **kwargs) ... >>> 'This decorator is unnecessary\n\n\n'.split('\n') ['This decorator is unnecessary', '', '', ''] >>> WeirdString('This decorator is unnecessary\n\n\n').split('\n') ['This decorator is unnecessary']

或更直接(以及更多的装饰精神使用):

>>> class WeirdString2(str): ... split = remove_empty(str.split) ... >>> WeirdString2('This decorator is unnecessary\n\n\n').split('\n') ['This decorator is unnecessary']

在这个特例中,我更喜欢显式过滤器。 但是我可以想象,例如,内置类的子类执行一些memoization或类似的东西。

It's possible in a sense; it depends on what exactly you mean. Decorator syntax like this...

@dec def foo(): pass

is really just sugar for this:

def foo(): pass foo = dec(foo)

So there's nothing to stop you from using a decorator on a predefined function in the global namespace.

func = dec(func)

But the methods of built-in classes live in the namespace of that class, and that namespace can't be modified directly, as chepner has already pointed out. That's a good thing, because it ensures that objects of type str will behave as expected! However, you could subclass str and decorate the method that way. (The below works in Python 2; in Python 3, pass the output of filter to a list. super also may work a little differently; I'll post a Python 3 update in the future.)

>>> def remove_empty(fn): ... def filtered(*args, **kwargs): ... return filter(lambda x: x != '', fn(*args, **kwargs)) ... return filtered ... >>> class WeirdString(str): ... @remove_empty ... def split(self, *args, **kwargs): ... return super(WeirdString, self).split(*args, **kwargs) ... >>> 'This decorator is unnecessary\n\n\n'.split('\n') ['This decorator is unnecessary', '', '', ''] >>> WeirdString('This decorator is unnecessary\n\n\n').split('\n') ['This decorator is unnecessary']

Or more directly (and so more in the spirit of decorator use):

>>> class WeirdString2(str): ... split = remove_empty(str.split) ... >>> WeirdString2('This decorator is unnecessary\n\n\n').split('\n') ['This decorator is unnecessary']

In the case of this particular example, I'd prefer an explicit filter. But I can imagine, for example, a subclass of a built-in class that does some memoization or something like that.

更多推荐

本文发布于:2023-08-05 09:43:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1431246.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自己的   有可能   应用于   将我   方法

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!