【问题标题】:self variable of class as an argument of a class method (python)类的自变量作为类方法的参数(python)
【发布时间】:2017-04-06 03:37:58
【问题描述】:

这是我的问题:

给定任意两个函数,例如。 f(x,a) 和 g(x,b),我想构建一个新函数,比如 F(f,g),它返回 f 和 g 的乘积。所以:

F(f,g) = f*g = f(x, a) * g(x, b) = F(x, a, b)

我希望尽可能少地进行这种硬编码。所以,对于 h(x, c, d),我会得到 F(f,h) = F(x, a, c, d)。 鉴于那时我想最小化 F,我想建立一个类。这是一个 MWE:

import numpy as np
from inspect import getargspec

def f(x, a):
    return np.tanh(x*a)

def g(x, b):
    return np.power(x,b)

def h(x, c, d):
    return x*c+np.log(x)

class fit_func(object):
    def __init__(self, data, *args):
        self.data = data
        self.func_a = args[0]
        self.func_b = args[1]
        self.args_a = getargspec(args[0])[0][1:]
        self.args_b = getargspec(args[1])[0][1:]

此时,我想到了包含以下__call__方法:

    def __call__(self, *self.args_a, *self.args_b):
        return self.func_a(self.data,self.args_a)*self.func_b(data,self.args_b)

我想:这样一个类的实例,比如F = fit_func(some_data_array,f,g),可以调用为F(a,b)。但是,python 不喜欢__call__ 的参数中的self.args_aself.args_b,我明白为什么。 有人知道获得这个的聪明方法吗?提前非常感谢您

【问题讨论】:

  • 我相信你的意思是 f(x, a) * g(x, b) = F(x, a, b)
  • 绝对 Mike 和我还更正了一件事:__call__ 方法的参数中 self.args_ab 前面的解包 *

标签: python class arguments


【解决方案1】:

如果您只接受位置参数,最好保存每个函数的参数长度,然后在调用方法中将 args 的适当切片传递给每个函数:

import numpy as np
from inspect import getargspec

class fit_func(object):
    def __init__(self, *args):
        self.func_a = args[0]
        self.func_b = args[1]
        self.size_arg_a = len(getargspec(self.func_a)[0])
        self.size_arg_b = len(getargspec(self.func_b)[0])
    def __call__(self, *args):
        return self.func_a(*args[:self.size_arg_a]) * self.func_b(*args[self.size_arg_b-1:])

演示:

def f(x, a):
    return np.tanh(x*a)

def h(x, c, d):
    return x*c+np.log(x)

F = fit_func(f, h)
print(F(3, 4, 3, 5, 7))
16.0986122875

如果您想将关键字参数传递给最终函数:

import numpy as np
from inspect import getargspec
from operator import itemgetter


class fit_func(object):
    def __init__(self, *args):
        self.func_a = args[0]
        self.func_b = args[1]
        self.arg_a = getargspec(self.func_a)[0]
        self.arg_b = getargspec(self.func_b)[0]

    def __call__(self, **kwargs):
        arg_a = itemgetter(*self.arg_a)(kwargs)
        arg_b = itemgetter(*self.arg_b)(kwargs)
        return self.func_a(*arg_a) * self.func_b(*arg_b)

演示:

def f(x, a):
    return np.tanh(x*a)

def h(x, c, d):
    return x*c+np.log(x)

F = fit_func(f, h)
print(F(x=3, a=4, c=5, d=7))
16.0986122875

【讨论】:

  • 如果我不想要位置参数而是调用__call__ 方法,其kwdargs 对应于函数fgh 的定义,该怎么办?所以F(f,h) = F(a=...,c=...,d=...)
  • 差不多了。在您的更新版本中,用户需要知道fh 的参数名称是什么。换句话说:有没有办法从F(f,h)获得getargspec(F)[0] = ['x', 'a' , 'c', 'd']
  • @andrea 为什么不,就做F.arg_a
  • 我需要一个新函数,其签名由F 实例化中提供的函数的额外参数(例如a,b)传递给 iminuit。我无法将其定义为def New_func(F.arg_a, F.arg_b): ....。我认为答案可能在 [stackoverflow.com/q/1409295/4349869] 但我不确定
猜你喜欢
  • 2019-03-22
  • 2020-10-26
  • 2020-05-12
  • 2016-10-13
  • 2013-02-22
  • 1970-01-01
  • 2013-02-17
  • 1970-01-01
  • 2018-11-22
相关资源
最近更新 更多