Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python3中函数多态性的Decorator方法_Python_Python Decorators_Parametric Polymorphism - Fatal编程技术网

Python3中函数多态性的Decorator方法

Python3中函数多态性的Decorator方法,python,python-decorators,parametric-polymorphism,Python,Python Decorators,Parametric Polymorphism,我有一个函数f,它接受参数I、a和Bi是计数器,a和B是列表或常量。如果是列表,该函数只添加A和B的第i个元素。以下是我用Python 3编写的内容 def const_or_list(i, ls): if isinstance(ls, list): return ls[i] else: return ls def f(i, A, B): _A = const_or_list(i, A) _B = const_or_list(i,

我有一个函数
f
,它接受参数
I
a
B
i
是计数器,
a
B
是列表或常量。如果是列表,该函数只添加
A
B
的第i个元素。以下是我用Python 3编写的内容

def const_or_list(i, ls):
    if isinstance(ls, list):
        return ls[i]
    else:
        return ls

def f(i, A, B):
    _A = const_or_list(i, A)
    _B = const_or_list(i, B)
    return _A + _B

M = [1, 2, 3]
N = 11
P = [5, 6, 7]
print(f(1, M, N)) # gives 13
print(f(1, M, P)) # gives 8
您会注意到,对两个(但不是全部)输入参数调用了
const\u或\u list()
函数。有没有一种装饰(大概更像Pythonic)的方法来实现我上面所做的

您可以执行以下操作:

def const_or_list(i, ls):
    if isinstance(ls, list):
        return ls[i]
    else:
        return ls

def f(*args):
    i_ip = args[0]
    result_list = []
    for i in range(1, len(args)):
        result_list.append(const_or_list(i_ip, args[i]))
    return sum(result_list)

M = [1, 2, 3]
N = 11
P = [5, 6, 7]
print(f(1, M, N)) # gives 13
print(f(1, M, P)) # gives 8

我认为在这种情况下,更多的蟒蛇不是与装饰。我将去掉
isinstance
,改用try/except,并去掉中间变量:

代码:

def const_or_list(i, ls):
    try:
        return ls[i]
    except TypeError:
        return ls

def f(i, a, b):
    return const_or_list(i, a) + const_or_list(i, b)
M = [1, 2, 3]
N = 11
P = [5, 6, 7]
Q = (5, 6, 7)
print(f(1, M, N))  # gives 13
print(f(1, M, P))  # gives 8
print(f(1, M, Q))  # gives 8
13
8
8
测试代码:

def const_or_list(i, ls):
    try:
        return ls[i]
    except TypeError:
        return ls

def f(i, a, b):
    return const_or_list(i, a) + const_or_list(i, b)
M = [1, 2, 3]
N = 11
P = [5, 6, 7]
Q = (5, 6, 7)
print(f(1, M, N))  # gives 13
print(f(1, M, P))  # gives 8
print(f(1, M, Q))  # gives 8
13
8
8
结果:

def const_or_list(i, ls):
    try:
        return ls[i]
    except TypeError:
        return ls

def f(i, a, b):
    return const_or_list(i, a) + const_or_list(i, b)
M = [1, 2, 3]
N = 11
P = [5, 6, 7]
Q = (5, 6, 7)
print(f(1, M, N))  # gives 13
print(f(1, M, P))  # gives 8
print(f(1, M, Q))  # gives 8
13
8
8
但我真的需要一个装饰师:

def const_or_list(i, ls):
    try:
        return ls[i]
    except TypeError:
        return ls

def f(i, a, b):
    return const_or_list(i, a) + const_or_list(i, b)
M = [1, 2, 3]
N = 11
P = [5, 6, 7]
Q = (5, 6, 7)
print(f(1, M, N))  # gives 13
print(f(1, M, P))  # gives 8
print(f(1, M, Q))  # gives 8
13
8
8
很好,但是代码要多得多

def make_const_or_list(param_num):
    def decorator(function):
        def wrapper(*args, **kwargs):
            args = list(args)
            args[param_num] = const_or_list(args[0], args[param_num])
            return function(*args, **kwargs)
        return wrapper
    return decorator

@make_const_or_list(1)
@make_const_or_list(2)
def f(i, a, b):
    return a + b

这可以帮助你谢谢你的回复。try-and-catch异常方法的优点。实际上,decorator方法在代码方面似乎更长。但它将最终函数简化为一个简单的线性函数。在我的实际用例中,公式要复杂得多,并且不断变化,清晰性是最重要的。