【问题标题】:How do I get the current file path in python dm-script如何在 python dm-script 中获取当前文件路径
【发布时间】:2020-08-20 07:37:17
【问题描述】:

我想在python 中获取Digital Micrograph 中当前文件的文件路径。我该怎么做?


我尝试使用

__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

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


一些背景

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

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

【问题讨论】:

    标签: python filepath dm-script


    【解决方案1】:

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

    import os
    os.getcwd()
    

    【讨论】:

    • 好主意,我忘了。但不幸的是它们并不相等,我只是测试了它:(
    【解决方案2】:

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

    GetApplicationDirectory("open_save",0)
    

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

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

    请注意,“当前”目录的概念在 Win10 上与应用程序(包括 GMS)有些不同。尤其是“SetApplicationDirectory”命令并不总是按预期工作......


    如果您想找出当前显示的特定文档的文件夹(图像或文本),您可以使用以下 DM 脚本。这里的假设是,窗口是最前面的窗口。

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

    【讨论】:

    • 所以测试这对我来说已经足够了。对于其他人:请注意,一旦您保存另一个文件,“open_save”目录就会更改为该目录!
    • @miile7 好吧,您可以使用列表中的其他“默认”目录之一...
    • 我需要执行脚本文件所在的目录,因为在同一个目录中还有其他需要导入的python文件。
    • (另外:只需将您的脚本文件保存在任何这些位置,即插件文件夹 f.e. 或其中任何一个的子文件夹或相对路径......)
    • 这听起来很有希望。我明天试试看。
    【解决方案3】:

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

    重要提示:这仅在您按下执行脚本按钮的python脚本窗口中有效,并且仅在保存此文件时才有效!但是从那里你可能正在导入应该提供module.__file__ 属性的脚本。这意味着这不适用于插件/库

    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__);
    

    【讨论】:

      猜你喜欢
      • 2021-11-02
      • 2011-02-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多