Python 如何在不使用全局变量的情况下编写函数中包含许多常量的公式,同时使其名称保持有意义?
我有一个函数,应该用ode解算器来解。问题是它有很多常数(比如100),同时我不想把它们放在一个数组中,因为很难理解公式(它们是化学物质)。此函数中的部分代码如下所示:Python 如何在不使用全局变量的情况下编写函数中包含许多常量的公式,同时使其名称保持有意义?,python,chemistry,Python,Chemistry,我有一个函数,应该用ode解算器来解。问题是它有很多常数(比如100),同时我不想把它们放在一个数组中,因为很难理解公式(它们是化学物质)。此函数中的部分代码如下所示: # Component: Calcium Fluxes J_rel = v1*(P_O1+P_O2)*(Ca_JSR - Ca_ss)*P_RyR # (micromolar_per_millisecond) J_tr = (Ca_NSR - Ca_JSR)/tau_tr # (micromolar_pe
# Component: Calcium Fluxes
J_rel = v1*(P_O1+P_O2)*(Ca_JSR - Ca_ss)*P_RyR # (micromolar_per_millisecond)
J_tr = (Ca_NSR - Ca_JSR)/tau_tr # (micromolar_per_millisecond)
J_leak = v2*(Ca_NSR - Ca_i) # (micromolar_per_millisecond)
J_up = ( v3*(Ca_i ^ 2.00000))/((K_m_up ^ 2.00000)+(Ca_i ^ 2.00000)) # (micromolar_per_millisecond)
J_xfer = (Ca_ss - Ca_i)/tau_xfer # (micromolar_per_millisecond)
P_RyR_prime = - 0.0400000*P_RyR - (( 0.100000*I_Ca_channels)/i_CaL_max)*(exp(( - ((V_m - 5.00000) ^ 2.00000)/648.000))) # (micromolar_per_millisecond)
如果我想把它们放到一个数组中,它会变成这样:
J_rel = algebraic[2]*(constants[21]+constants[3])*(constants[4] - Ca_ss)*P_RyR # (micromolar_per_millisecond)
J_tr = (Ca_NSR - Ca_JSR)/tau_tr # (micromolar_per_millisecond)
J_leak = constants[31]*(Ca_NSR - Ca_i) # (micromolar_per_millisecond)
J_up = ( constants[69]*(Ca_i ^ 2.00000))/((constants[17] ^ 2.00000)+(Ca_i ^ 2.00000)) # (micromolar_per_millisecond)
J_xfer = (Ca_ss - Ca_i)/tau_xfer # (micromolar_per_millisecond)
P_RyR_prime = - 0.constants[5]*P_RyR - (( 0.100000*constants[65])/constants[43])*(exp(( - ((V_m - constants[4]) ^ 2.00000)/constants[34]))) # (micromolar_per_millisecond)
很难“看到”实际公式。我必须将常量定义为全局变量吗?此函数由ode解算器使用,迭代次数约为50000次。所以我需要一些高效的东西
另外,我正在使用python(scipy库),但我认为在其他语言中也可能存在同样的问题
非常感谢如果您想避免污染名称空间,可以使用字典:
c = { 'Ca_NSR' : 1.5, ... }
J_rel = v1*(P_O1+P_O2)*(c['Ca_JSR'] - c['Ca_ss'])*P_RyR
您还可以使用一个类:
def Constants(object):
def __init__(self):
self.Ca_NSR = 1.5
# etc...
c = Constants()
J_rel = v1*(P_O1+P_O2)*(c.Ca_JSR - c.Ca_ss)*P_RyR
如果要避免污染命名空间,可以使用字典:
c = { 'Ca_NSR' : 1.5, ... }
J_rel = v1*(P_O1+P_O2)*(c['Ca_JSR'] - c['Ca_ss'])*P_RyR
您还可以使用一个类:
def Constants(object):
def __init__(self):
self.Ca_NSR = 1.5
# etc...
c = Constants()
J_rel = v1*(P_O1+P_O2)*(c.Ca_JSR - c.Ca_ss)*P_RyR
您可以使用函数关键字参数将dict“解包”到本地命名空间中:
c = { 'Ca_NSR' : 1.5, ... }
def f(Ca_JSR, Ca_ss, ...):
J_rel = v1*(P_O1+P_O2)*(Ca_JSR - Ca_ss)*P_RyR
f(**c)
有关f(**c)含义的详细信息,请参阅上的文档。您可以使用函数关键字参数将dict“解包”到本地命名空间中:
c = { 'Ca_NSR' : 1.5, ... }
def f(Ca_JSR, Ca_ss, ...):
J_rel = v1*(P_O1+P_O2)*(Ca_JSR - Ca_ss)*P_RyR
f(**c)
有关f(**c)的详细信息,请参阅上的文档。仔细想想,为什么不使用全局变量呢?它会给你一个漂亮、简单、快速的结果。在python中,全局变量将被限制在定义它们的模块中,因此您不必像在C中那样担心它们会污染整个程序。仔细想想,为什么不只使用全局变量呢?它会给你一个漂亮、简单、快速的结果。在python中,全局变量将被限制为在中定义的模块,因此,您不必担心它们会像在C中那样污染整个程序。似乎是答案,但让我来看看scipy ode解算器是否可以处理此问题。似乎是答案,但让我来看看scipy ode解算器是否可以处理此问题。问题是什么效率?我听说在MATLAB中,每次调用函数时,它都会将所有全局变量复制到函数中。因此,如果您想运行50000的函数,这将成为一个问题。在这里,效率对我来说很重要,不会污染范围。如果效率很重要,我将使用globals和其他一些方案,使用
timeit
模块来分析您的代码,看看哪一个能提供更好的性能。这是说服你自己的最好方法,然后你有足够的数据来做出明智的决定。效率如何?我听说在MATLAB中,每次调用函数时,它都会将所有全局变量复制到函数中。因此,如果您想运行50000的函数,这将成为一个问题。在这里,效率对我来说很重要,不会污染范围。如果效率很重要,我将使用globals和其他一些方案,使用timeit
模块来分析您的代码,看看哪一个能提供更好的性能。这是说服你自己的最好方法,然后你就有了硬数字来做出明智的决定。这个例子有助于解释发生了什么:c={'CA_NSR':1.5,…};foo(**c)与foo(CA_NSR=c['CA_NSR'],…)相同。这个例子有助于解释发生了什么:c={'CA_NSR':1.5,…};foo(**c)与foo相同(CA_NSR=c['CA_NSR'],…)