是否可以将自己的装饰器应用于Python中的内置方法? [英] Is it possible to apply my own decorators to builtin methods in Python?

查看:79
本文介绍了是否可以将自己的装饰器应用于Python中的内置方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

为此:

some_string.split('\n')

以便删除空字符串。可能吗?甚至是个好主意?

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

推荐答案

从某种意义上讲是可能的;这取决于您的意思。这样的装饰器语法...

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

@dec
def foo():
    pass

实际上只是糖:

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)

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

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.

这篇关于是否可以将自己的装饰器应用于Python中的内置方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆