Por alguna razón, no puedo pasar las variables en kwargs en Python para que las vea la función receptora. (RESUELTO - ver edición). Esto ilustra el problema: los parámetros kwargs se pasan a través de varias funciones y llegan a la integrandfunción. Puse una impresión (kwargs) allí que muestra todo el diccionario que creé en las primeras líneas a continuación. PERO estas variables no son vistas por la integrandfunción y se produce un error. ¿Cuál es la forma correcta de hacer que estas variables sean accesibles para la función final? Muy apreciado, busqué bastantes publicaciones en SO pero no pude encontrar algo directamente relevante para mi caso.
ntegrand(x, F, K, T1, T2, vol, flag):
print(kwargs)
d1 = (np.log(x / (x+K)) + 0.5 * (vol**2) * (T2-T1)) / (vol * np.sqrt(T2 - T1))
d2 = d1 - vol*np.sqrt(T2 - T1)
mu = np.log(F) - 0.5 *vol**2 * T1
sigma = vol * np.sqrt(T1)
value = lognorm.pdf(x, scale=np.exp(mu), s=sigma) * (flag * x*norm.cdf(flag * d1) - flag * (x+K)*norm.cdf(flag * d2))
return value
def integrate(x, w, a, **kwargs):
return np.sum(w*transform_integral_negative1_1_to_0_1(x, a, **kwargs))
def transform_integral_0_1_to_Infinity(x, a, **kwargs):
return integrand(a+(x/(1-x)), **kwargs) *(1/(1-x)**2);
def transform_integral_negative1_1_to_0_1(x, a, **kwargs):
return 0.5 * transform_integral_0_1_to_Infinity((x+1)/2, a, **kwargs)
flag = current_opt[i,0]
F = current_opt[i,1]
K = current_opt[i,2]
T2 = current_opt[i,3]
T1 = current_opt[i,4]
r = current_opt[i,5]
vol = current_opt[i,6]
a = 0
b = np.Inf
kwargs = {'flag':flag, 'F':F, 'K':K, 'vol':vol, 'T2':T2, 'T1':T1}
integrate(x, w, a, **kwargs)
Y esto es lo que se imprime antes de que salga el error print(kwargs):
{'F': 1.2075, 'flag': -1.0, 'K': 0.12509999999999999, 'T2': 0.068500000000000005, 'vol': 0.42999999999999999, 'T1': 0.041099999999999998}
Y el error, a pesar de que K se definió anteriormente:
NameError: name 'K' is not defined
La solución fue definir cada entrada en lugar de extraer cada valor del diccionario... La **kwargsfunción pasada a la última extrae todos los argumentos de palabras clave automáticamente.
**kwargsse pasa como dicta la función, no llena automáticamente los locales de la función.
p.ej:
kwargs = {'K': 1}
def foo(**kwargs):
print(K)
def bar(**kwargs):
print(kwargs['K'])
foo(**kwargs) # NameError
bar(**kwargs) # Works Ok.