如何在 python dm-script 中获取当前文件路径

How do I get the current file path in python dm-script

我想在python中获取数码显微中当前文件的文件路径。我该怎么做?


我尝试使用

__file__

但我得到 NameError: Name not found globally.

我尝试使用 dm-script GetCurrentScriptSourceFilePath() 和以下代码来获取 python

的值
import DigitalMicrograph as DM
import time
    
# get the __file__ by executing dm-scripts GetCurrentScriptSourceFilePath()
# function, then save the value in the persistent tags and delete the key
# again
tag = "__python__file__{}".format(round(time.time() * 100))
DM.ExecuteScriptString(
    "String __file__;\n" + 
    "GetCurrentScriptSourceFilePath(__file__);\n" + 
    "number i = GetPersistentTagGroup().TagGroupCreateNewLabeledTag(\"" + tag + "\");\n" + 
    "GetPersistentTagGroup().TagGroupSetIndexedTagAsString(i, __file__);\n"
);
_, __file__ = DM.GetPersistentTagGroup().GetTagAsString(tag);
DM.ExecuteScriptString("GetPersistentTagGroup().TagGroupDeleteTagWithLabel(\"" + tag + "\");")

但是GetCurrentScriptSourceFilePath()函数似乎不包含路径(这是有道理的,因为它是从字符串执行的)。

我发现 this post 推荐

import inspect
src_file_path = inspect.getfile(lambda: None)

但是 src_file_path"<string>" 这显然是错误的。

我尝试引发异常,然后使用以下代码获取它的文件名

try:
    raise Exception("No error")
except Exception as e:
    exc_type, exc_obj, exc_tb = sys.exc_info()
    filename = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
    print("File: ", filename)

但我再次得到 <string> 作为 filename

我试图从脚本中获取路径 window 但我找不到任何函数来获取它。但是脚本 window 必须知道它的路径在哪里,否则 Ctrl+S 无法工作。


一些背景

我正在开发一个用于数码显微照片的模块。我也有测试文件。但是要在测试文件中导入(仍在开发的)模块,我需要相对于测试文件的路径。

稍后模块将安装在某个地方,所以这应该不是问题。但是为了提供一组完整的测试,我希望能够在不必安装(不工作的)模块的情况下执行测试。

对于当前工作目录的文件路径,请使用:

import os
os.getcwd()

在您可以从 Python 脚本调用的 DM-script 中,命令 GetApplicationDirectory() 提供了您所需要的。通常,您会希望使用“open_save”,即

GetApplicationDirectory("open_save",0)

这将 return 使用 File/Open 或 File/Save 用于新图像时出现的目录(字符串变量)。但是,它不是用于“File/Save 工作区”或其他保存的内容。

来自关于该命令的 F1 帮助文档:

请注意,“当前”目录的概念在 Win10 上与应用程序有些冲突 - 包括 GMS.In 特别是“SetApplicationDirectory”命令并不总是按预期工作...


如果您想找出当前显示的特定文档(图像或文本)的文件夹是什么,您可以使用以下 DM-script。这里的假设是 window 是 front-most window.

documentwindow win = GetDocumentWindow(0)
if ( win.WindowIsvalid() )
    if ( win.WindowIsLinkedToFile() )
        Result("\n" + win.WindowGetCurrentFile())
    

对于所有也需要这个(并且只想复制一些代码)的人,我根据@BmyGuests 的回答创建了以下代码。这会获取脚本 window 绑定的文件并将其保存为持久标记。然后从 python 文件中读取此标签(并删除标签)。

重要说明:这仅适用于 python 脚本 window,您可以在其中按 执行脚本 按钮,并且仅当此文件已保存时!但是从那里开始,您可能正在导入应该提供 module.__file__ 属性的脚本。这意味着 不适用于 plugins/libraries

import DigitalMicrograph as DM

# the name of the tag is used, this is deleted so it shouldn't matter anyway
file_tag_name = "__python__file__"
# the dm-script to execute, double curly brackets are used because of the 
# python format function
script = ("\n".join((
    "DocumentWindow win = GetDocumentWindow(0);",
    "if(win.WindowIsvalid()){{",
        "if(win.WindowIsLinkedToFile()){{",
            "TagGroup tg = GetPersistentTagGroup();",
            "if(!tg.TagGroupDoesTagExist(\"{tag_name}\")){{",
                "number index = tg.TagGroupCreateNewLabeledTag(\"{tag_name}\");",
                "tg.TagGroupSetIndexedTagAsString(index, win.WindowGetCurrentFile());",
            "}}",
            "else{{",
                "tg.TagGroupSetTagAsString(\"{tag_name}\", win.WindowGetCurrentFile());",
            "}}",
        "}}",
    "}}"
))).format(tag_name=file_tag_name)

# execute the dm script
DM.ExecuteScriptString(script)

# read from the global tags to get the value to the python script
global_tags = DM.GetPersistentTagGroup()
if global_tags.IsValid():
    s, __file__ = global_tags.GetTagAsString(file_tag_name);
    if s:
        # delete the created tag again
        DM.ExecuteScriptString(
            "GetPersistentTagGroup()." + 
            "TagGroupDeleteTagWithLabel(\"{}\");".format(file_tag_name)
        )
    else:
        del __file__

try:
    __file__
except NameError:
    # set a default if the __file__ could not be received
    __file__ = ""
    
print(__file__);