我刚刚遇到了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 filteredTo 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(): passis 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.
更多推荐
发布评论