簡體   English   中英

如何組合兩個采用相同參數的函數?

[英]How can I combine two functions that take the same arguments?

我有一個給定的功能

def unnorm(x, alpha, beta):
    return (1 + alpha * x + beta * x ** 2)

然后我將其集成以查找范圍內的歸一化常量,並將其轉換為lambda函數,該函數采用與unnorm相同的參數。 現在,為了創建一個合適的對象,我將這些函數組合在一起:

def normalized(x, alpha, beta):
    return unnorm(x, alpha, beta) * norm(x, alpha, beta)

這很好,但仍然有重復,並從全局命名空間中提取名稱。

如何以更干凈的方式組合這兩個功能,而無需重新編寫參數? 例如

def normalized(func, normalizer):
    return func * normalizer

完整代碼:

import sympy
import numpy as np
import inspect

def normalize_function(f, xmin, xmax):
    """
    Normalizes function to PDF in the given range
    """
    # Get function arguments
    fx_args = inspect.getfullargspec(f).args
    # Convert to symbolic notation
    symbolic_args = sympy.symbols(fx_args)
    # Find definite integral
    fx_definite_integral = sympy.integrate(f(*symbolic_args), (symbolic_args[0], xmin, xmax))
    # Convert to a normalization multiplication term, as a real function
    N = sympy.lambdify(expr = 1 / fx_definite_integral, args = symbolic_args)
    return N

def unnorm(x, alpha, beta):
    return (1 + alpha * x + beta * x ** 2)

norm = normalize_function(unnorm, -1, 1)

# How do I condense this to a generic expression?
def normalized(x, alpha, beta):
    return unnorm(x, alpha, beta) * norm(x, alpha, beta)

x = np.random.random(100)

print(normalized(x, alpha = 0.5, beta = 0.5))

我現在所做的事情沒有任何問題。 但出於審美目的,這里有一些具有一些最小功能的替代方案。

def doubler(x, y, z):
    return 2*(x + y + z)

def halver(x, y, z):
    return 0.5*(x + y + z)

def doubler_halver_sumprod(*args):
    return doubler(*args) * halver(*args)

dhs = lambda *args: doubler(*args) * halver(*args)

doubler_halver_sumprod(1, 2, 3)  # 36
dhs(1, 2, 3)                     # 36

如果你想要一個真正可擴展的,功能性的方法,一次提取參數,這可能有效:

from operator import mul, methodcaller
from functools import reduce

def prod(iterable):
    return reduce(mul, iterable, 1)

def doubler(x, y, z):
    return 2*(x + y + z)

def halver(x, y, z):
    return 0.5*(x + y + z)

def dhs2(*args):
    return prod(map(methodcaller('__call__', *args), (doubler, halver)))

def dhs3(*args):
    return prod(f(*args) for f in (doubler, halver))

dhs2(1, 2, 3)  # 36
dhs3(1, 2, 3)  # 36

好吧,一種方法是實現*等功能的裝飾器:

class composable:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        return self.func(*args, **kwargs)

    def __mul__(self, other):
        if callable(other):
            def wrapper(*args, **kwargs):
                return self(*args, **kwargs) * other(*args, **kwargs)
            return self.__class__(wrapper)
        return NotImplemented

@composable
def f(x):
    return 2 * x

@composable
def g(x):
    return x + 1

h = f * g # (2*x) * (x+1)
print(h(2))
# 12

您需要為__add__ __sub____div__ __rmul__

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM