You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python传递带参函数作为另一函数参数时遇TypeError问题求助

问题:高斯积分传递被积函数时触发TypeError

我在WKB函数中尝试将integrand函数以int_gauss(integrand(E,x0,m1,x),xp,wp)的形式传入int_gauss作为参数,收到如下错误:

TypeError: 'numpy.ndarray' object is not callable

我已经通过在int_gauss内直接实现integrand的计算逻辑得到了预期结果,但希望能实现将integrand作为参数传入int_gauss的调用方式。

原报错代码

x0=1
m1=1
h=1
e=100


import numpy as np
import matplotlib.pyplot as plt
def gaussxw(N):

    a = np.linspace(3,4*N-1,N)/(4*N+2)
    x = np.cos(np.pi*a+1/(8*N*N*np.tan(a)))

    # Find roots using Newton's method
    epsilon = 1e-15
    delta = 1.0
    while delta>epsilon:
        p0 = np.ones(N,float)
        p1 = np.copy(x)
        for k in range(1,N):
            p0,p1 = p1,((2*k+1)*x*p1-k*p0)/(k+1)
        dp = (N+1)*(p0-x*p1)/(1-x*x)
        dx = p1/dp
        x -= dx
        delta = max(abs(dx))

    # Calculate the weights
    w = 2*(N+1)*(N+1)/(N*N*(1-x*x)*dp*dp)

    return x,w

def gaussxwab(N,a,b):
    x,w = gaussxw(N)
    return 0.5*(b-a)*x+0.5*(b+a),0.5*(b-a)*w

N = 50
x, w = gaussxw(N)
 
def integrand(E,x0,m1,x):
    return    np.sqrt((2*m1*(E-    (e*( ((x0/x)**12) -2*((x0/x)**6)   )   ))))

def WKB(E,x0,e):
    a, b = x0*(1+np.sqrt(1+(E/e)))**(-1/6), x0*(1-np.sqrt(1+(E/e)))**(-1/6)
    xp = 0.5*(b - a)*x + 0.5*(b + a) 
    wp = 0.5*(b - a)*w  
    return int_gauss(integrand(E,x0,m1,x),xp,wp)

def int_gauss(f,nodes, weights):
  result = 0.0
  for x, w in zip(nodes, weights):
    result += w *f(x)
  return result



plt.close()
En=np.linspace(-100,-1,496)
W=[WKB(i,x0,e) for i in En]
plt.figure()
plt.plot(En,W)
plt.grid()
plt.axis()

plt.show()

已实现功能的代码(但未传递函数参数)

def WKB(E,x0,e):
    a, b = x0*(1+np.sqrt(1+(E/e)))**(-1/6), x0*(1-np.sqrt(1+(E/e)))**(-1/6)
    xp = 0.5*(b - a)*x + 0.5*(b + a) 
    wp = 0.5*(b - a)*w  
    return int_gauss(E,x0,m1,xp,wp)

def int_gauss(E,x0,m1,nodes, weights):
  result = 0.0
  for x, w in zip(nodes, weights):
    result += w * np.sqrt((2*m1*(E-    (e*( ((x0/x)**12) -2*((x0/x)**6)   )   ))))
  return result

解决方案

错误原因

integrand(E,x0,m1,x)会直接执行函数,返回一个numpy数组,而int_gauss需要的是一个可调用的函数(能接收x参数并返回对应值),所以触发了"numpy数组不可调用"的错误。

修复方法

需要将E、x0、m1这些固定参数绑定到integrand上,生成一个只需要接收x参数的可调用函数,有两种简单实现方式:

方法1:使用lambda表达式

修改WKB函数中的调用代码:

def WKB(E,x0,e):
    a, b = x0*(1+np.sqrt(1+(E/e)))**(-1/6), x0*(1-np.sqrt(1+(E/e)))**(-1/6)
    xp = 0.5*(b - a)*x + 0.5*(b + a) 
    wp = 0.5*(b - a)*w  
    # 用lambda绑定固定参数,生成仅接收x的函数
    return int_gauss(lambda x_val: integrand(E, x0, m1, x_val), xp, wp)

方法2:使用functools.partial

先导入partial,再修改WKB函数:

from functools import partial

def WKB(E,x0,e):
    a, b = x0*(1+np.sqrt(1+(E/e)))**(-1/6), x0*(1-np.sqrt(1+(E/e)))**(-1/6)
    xp = 0.5*(b - a)*x + 0.5*(b + a) 
    wp = 0.5*(b - a)*w  
    # 绑定固定参数,生成可调用的函数对象
    bound_integrand = partial(integrand, E, x0, m1)
    return int_gauss(bound_integrand, xp, wp)

两种方法都能让int_gauss接收到一个可调用的函数,在循环中调用f(x)时,会自动用当前的节点值x去计算对应的被积函数值,最终完成高斯积分计算。

内容的提问来源于stack exchange,提问作者VisCCelludamtan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 04:05:40