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

如果这不起作用,您可以尝试在两种方法中进行加载调用,但这似乎效率不高。