python 的 "in memory" 变量如何工作
How do python's "in memory" variables work
我试图了解“内存中”在 python 中是如何工作的。根据我的理解,它是一个不存储在任何地方而只是在内存中浮动的变量。我不太确定如何正确措辞。
澄清一下,我正在使用 PyKEP 模块并且正在加载 SPICE 内核 pykep.util.load_spice_kernel('kernel_name.bsp')
。 Link to the documentation
当我这样做时,我在全局范围内没有新变量。但是,它允许我随后访问我将调用的小行星的更多数据(速度、位置等)。
asteroid = pk.planet.spice(spiceID, 'SUN', 'ECLIPJ2000', 'NONE', pk.MU_SUN, mu_self, self_radius, self_radius * 1.05)
我现在可以在全局范围内使用 asteroid.eph(epoch)
而不会出现任何错误。但是,如果我在其他地方定义它或者尝试移动它,情况就不是这样了。
例如:
示例 1:函数
注意pk是下面的PyKEP模块。
def loadKernel(name = 'de440s_Ryugu.bsp', spiceID = '162173', mu_self = 30.03336, self_radius = 432.5):
pk.util.load_spice_kernel(name)
asteroid = pk.planet.spice(spiceID, 'SUN', 'ECLIPJ2000', 'NONE', pk.MU_SUN, mu_self, self_radius, self_radius * 1.05)
return asteroid
在函数的本地范围内我可以使用 asteroid.eph(epoch)
但在外部我需要重新执行第一行。这是有道理的。但是,为什么我不能 return 它到全局范围。
示例 2:内部 objects/classes
class Trajectory:
def __init__(
self,
seq=[pk.planet.gtoc7(3413), pk.planet.gtoc7(
234), pk.planet.gtoc7(11432)])
# We define data members:
self.__seq = seq
def velAndPos(self):
r, v = self.__seq[i + 1].eph(end)
return r, v
这里我会遇到一个错误,说内核文件没有加载,即使我在velAndPos方法中添加pykep.util.load_spice_kernel('kernel_name.bsp')
作为第一行。为什么会这样?是因为__seq
是女贞吗?
此外,使用“内存中”变量的优势是什么?
提前致谢。
您可以先在全局范围内创建一个变量作为“全局变量”,然后再在函数定义中使用它,然后在函数内部将其声明为“全局”。这是一个可能对您有所帮助的示例:
globvar = 0
def set_globvar_to_one():
global globvar # Needed to modify global copy of globvar
globvar = 1
def print_globvar():
print(globvar) # No need for global declaration to read value of globvar
set_globvar_to_one()
print_globvar() # Prints 1
这里有一个 link 到讨论这个主题的线程:Using global variables in a function
尽我所能回答你的问题,但如果有人知道更好,请在评论中纠正我。
内存变量是如何工作的?
链接 here you'll see that python and other high-level languages use a symbol table to map a variable name to the address it represents
. And from the PyKep docs 您会发现您对该实用程序的调用将内核加载到内存中。此时,正在执行您的 python 进程的进程的页面 table 知道内核已加载到何处。
它如何应用于您的代码(最佳猜测)
如果没有看到您的项目结构,很难准确地说,但我会试一试。我的猜测是您没有正确排序对需要加载内核的 methods/attributes 的调用。例如,如果您仅在调用函数时加载内核,则在调用该函数之前,该内核不会存在于进程中。
我快速浏览了 pykep
,我怀疑有些混淆是因为它是用 C++ 实现的,并且绑定到 Python。
内核似乎是加载函数带入内存的二进制数据文件,然后其他 pykep
函数可以访问它们(同样,在幕后都是 C++)。
因此,您没有看到数据显示为 Python 个变量也就不足为奇了。
现在,关于您的代码 - 使用 classes 管理数据是一个很好的做法。实际上,您可以在 class 定义范围内 运行 任意代码,因此我认为以下代码很有可能起作用:
class Trajectory:
pk.util.load_spice_kernel(name)
def __init__(self, seq=None, name=None):
if seq is None:
# don't use something mutable as your default value,
# else modifying it also modify the default behaviour
seq = [
pk.planet.gtoc7(3413),
pk.planet.gtoc7(234),
pk.planet.gtoc7(11432)
]
# We define data members:
self.__seq = seq
def velAndPos(self):
r, v = self.__seq[i + 1].eph(end)
return r, v
如果这不起作用,您可以尝试在两种方法中进行加载调用,但这似乎效率不高。
我试图了解“内存中”在 python 中是如何工作的。根据我的理解,它是一个不存储在任何地方而只是在内存中浮动的变量。我不太确定如何正确措辞。
澄清一下,我正在使用 PyKEP 模块并且正在加载 SPICE 内核 pykep.util.load_spice_kernel('kernel_name.bsp')
。 Link to the documentation
当我这样做时,我在全局范围内没有新变量。但是,它允许我随后访问我将调用的小行星的更多数据(速度、位置等)。
asteroid = pk.planet.spice(spiceID, 'SUN', 'ECLIPJ2000', 'NONE', pk.MU_SUN, mu_self, self_radius, self_radius * 1.05)
我现在可以在全局范围内使用 asteroid.eph(epoch)
而不会出现任何错误。但是,如果我在其他地方定义它或者尝试移动它,情况就不是这样了。
例如:
示例 1:函数
注意pk是下面的PyKEP模块。
def loadKernel(name = 'de440s_Ryugu.bsp', spiceID = '162173', mu_self = 30.03336, self_radius = 432.5):
pk.util.load_spice_kernel(name)
asteroid = pk.planet.spice(spiceID, 'SUN', 'ECLIPJ2000', 'NONE', pk.MU_SUN, mu_self, self_radius, self_radius * 1.05)
return asteroid
在函数的本地范围内我可以使用 asteroid.eph(epoch)
但在外部我需要重新执行第一行。这是有道理的。但是,为什么我不能 return 它到全局范围。
示例 2:内部 objects/classes
class Trajectory:
def __init__(
self,
seq=[pk.planet.gtoc7(3413), pk.planet.gtoc7(
234), pk.planet.gtoc7(11432)])
# We define data members:
self.__seq = seq
def velAndPos(self):
r, v = self.__seq[i + 1].eph(end)
return r, v
这里我会遇到一个错误,说内核文件没有加载,即使我在velAndPos方法中添加pykep.util.load_spice_kernel('kernel_name.bsp')
作为第一行。为什么会这样?是因为__seq
是女贞吗?
此外,使用“内存中”变量的优势是什么?
提前致谢。
您可以先在全局范围内创建一个变量作为“全局变量”,然后再在函数定义中使用它,然后在函数内部将其声明为“全局”。这是一个可能对您有所帮助的示例:
globvar = 0
def set_globvar_to_one():
global globvar # Needed to modify global copy of globvar
globvar = 1
def print_globvar():
print(globvar) # No need for global declaration to read value of globvar
set_globvar_to_one()
print_globvar() # Prints 1
这里有一个 link 到讨论这个主题的线程:Using global variables in a function
尽我所能回答你的问题,但如果有人知道更好,请在评论中纠正我。
内存变量是如何工作的?
链接 here you'll see that python and other high-level languages use a symbol table to map a variable name to the address it represents
. And from the PyKep docs 您会发现您对该实用程序的调用将内核加载到内存中。此时,正在执行您的 python 进程的进程的页面 table 知道内核已加载到何处。
它如何应用于您的代码(最佳猜测) 如果没有看到您的项目结构,很难准确地说,但我会试一试。我的猜测是您没有正确排序对需要加载内核的 methods/attributes 的调用。例如,如果您仅在调用函数时加载内核,则在调用该函数之前,该内核不会存在于进程中。
我快速浏览了 pykep
,我怀疑有些混淆是因为它是用 C++ 实现的,并且绑定到 Python。
内核似乎是加载函数带入内存的二进制数据文件,然后其他 pykep
函数可以访问它们(同样,在幕后都是 C++)。
因此,您没有看到数据显示为 Python 个变量也就不足为奇了。
现在,关于您的代码 - 使用 classes 管理数据是一个很好的做法。实际上,您可以在 class 定义范围内 运行 任意代码,因此我认为以下代码很有可能起作用:
class Trajectory:
pk.util.load_spice_kernel(name)
def __init__(self, seq=None, name=None):
if seq is None:
# don't use something mutable as your default value,
# else modifying it also modify the default behaviour
seq = [
pk.planet.gtoc7(3413),
pk.planet.gtoc7(234),
pk.planet.gtoc7(11432)
]
# We define data members:
self.__seq = seq
def velAndPos(self):
r, v = self.__seq[i + 1].eph(end)
return r, v
如果这不起作用,您可以尝试在两种方法中进行加载调用,但这似乎效率不高。