简体   繁体   English

使用装饰器更改已装饰 function 的参数

[英]Use decorator to change argument of a decorated function

Background背景

I want to perform different methods to the same data.我想对相同的数据执行不同的方法。 Different methods are variants of an original method, only with different arguments for param:p3 .不同的方法是原始方法的变体,只有param:p3的 arguments 不同。

# This is original method
def method(p1,p2,p3,data):
    return data + p1 + p2 + p3
method(p1=1, p2=2, p3=3, data=10)

16 16

# By changing param:p3, I can define 3 methods based on original method.
# but it seems stupid and very unclear...
def method1(*args, **kw):
    return method(*args, **kw, p3 = 1)
def method2(*args, **kw):
    return method(*args, **kw, p3 = 2)
def method3(*args, **kw):
    return method(*args, **kw, p3 = 3)
method1(p1=1,p2=2,data =10),\
method2(p1=1,p2=3, data =100)

(14,106) (14,106)

Question问题

Is there any decorator to revise my original method to any variant, like method1 ?是否有任何装饰器可以将我的原始method修改为任何变体,例如method1

# After decorated, method equals to method1
@decorator(p3 = 1)
def method(p1,p2,p3,data):
    return data + p1 + p2 + p3

# After decorated, method equals to method2
@decorator(p3 = 2)
def method(p1,p2,p3,data):
    return data + p1 + p2 + p3

Or, Shouldn't I use a decorator to satisfy my demand, maybe a class instead?或者,我不应该使用装饰器来满足我的需求,也许是 class 吗?

To flesh out rchome's comment, you can use functools.partial as follows:要充实 rchome 的注释,您可以使用 functools.partial 如下:

>>> from functools import partial
>>> def method(p1,p2,p3,data):
...     return data + p1 + p2 + p3
>>> method1 = partial(method, p3=1)
>>> method2 = partial(method, p3=2)
>>> method3 = partial(method, p3=3)
>>> method1(p1=1,p2=2,data=10)
14
>>> method2(p1=1,p2=2,data=10)
15
>>> method3(p1=1,p2=2,data=10)
16

We can use decorator to do the same thing as follows:我们可以使用装饰器来做同样的事情,如下所示:

# this is a decorator factory
def de_fac(**out_kw):
    def my_decorator(f):
        def wrapper(*args, **kw):
            print('inside function arguments:',{*args})
            print('inside function keywords:',{**kw})
            print("outside decorator factory\'s arguments:", {**out_kw})
            # override {**kw} with {**out_kw}
            return f(*args, **{**kw, **out_kw})
        return wrapper
    return my_decorator


@de_fac(p3=1)
def method_to_be_dec(p1,p2,p3,data):
    return data + p1 + p2 + p3

# it's same
method_to_be_dec(p1=1, p2=2, data=10), method1(p1=1, p2=2, data=10)

inside function arguments: set() function arguments 内部:设置()
inside function keywords: {'p1': 1, 'p2': 2, 'data': 10} function 里面的关键字:{'p1': 1, 'p2': 2, 'data': 10}
outside decorator factory's arguments: {'p3': 1}外部装饰厂的 arguments: {'p3': 1}
(14, 14) (14, 14)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用装饰器将参数添加到装饰函数 - Use decorator to add an argument to the decorated function 如何在装饰器中使用 pytest 固定装置而不将其作为装饰 function 的参数 - How to use pytest fixtures in a decorator without having it as argument on the decorated function 在Python装饰器中创建参数以供装饰函数使用 - Creating parameters in a Python decorator for use by the decorated function 在Python 3中访问装饰器内部装饰函数的关键字参数失败 - Accessing keyword argument of decorated function inside the decorator fails in Python 3 python 装饰器如何更改装饰 function 中的调用? - how can a python decorator change calls in decorated function? 类中的装饰器:无法在装饰函数内部使用self - Decorator in class: cannot use self inside the decorated function 带装饰函数参数的python decorator - python decorator with arguments of decorated function 如何在装饰器中使用上下文管理器以及如何将在decorator中创建的对象传递给装饰函数 - How to use a context manager inside a decorator and how to pass an object created in decorator to decorated function 传入装饰的参数 function - Argument passing in decorated function 当我调用内部/装饰函数时,我可以将参数传递给我的装饰器函数吗? - Can I pass an argument into my decorator function when I call the inner/decorated function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM