是否可以将自己的装饰器应用于Python中的内置方法? [英] Is it possible to apply my own decorators to builtin methods in 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屋!