<p>若要在<code>dm-script</code>和<code>python</code>之间同步数据,同时两者都在同一实例中运行(在本例中,线程也可以针对不同的线程进行修改),可以使用<strong>持久标记</p>
<p><code>dm-script</code>正在设置持久标记<code>python</code>然后可以再次读取持久性标记</p>
<hr/>
<h2>更新:Python模块</h2>
<p>由于下面提到的限制以及不断增长且不可读的代码,我决定为此编写自己的python模块。使用<a href="https://github.com/miile7/execdmscript" rel="nofollow noreferrer">^{<cd5>}</a>可以很容易地从数字显微照片执行具有变量同步的dm脚本代码</p>
<p>请查看以下示例:</p>
<pre class="lang-py prettyprint-override"><code>from execdmscript import exec_dmscript
# some script to execute
dmscript = """
number input;
number s = GetNumber("Enter a number between " + min + " and " + max + ".", init, input);"
"""
# variables that will be defined for the dm-scripts (and readable later on in python)
sv = {"min": 1, "max": 10, "init": 2}
# variables the dm-script defines and that should be readable in the python file
rv = {"input": "number", "s": "number"}
with exec_dmscript(dmscript, readvars=rv, setvars=sv) as script:
if script["s"]:
print(script["input"])
else:
print("User pressed cancel.")
</code></pre>
<p>这隐藏了所有与dm脚本相关的保存和问题(如下所述)。它允许使用<code>list</code>和<code>dict</code>以及<code>bool</code>、<code>str</code>、<code>int</code>和<code>float</code>等基本类型。所有类型和值都可以以pythonic的方式使用,而无需关心dm脚本类型。dm脚本可以移动到一个单独的文件中,以进一步清理代码</p>
<p>请注意,对于调试,有一个<code>exec_dmscript(debug=True, debug_file="path/to/file")</code>开关将代码保存到给定的<code>debug_file</code>。然后可以在GMS中手动执行该文件,显示错误</p>
<blockquote>
<p><strong>Disclaimer</strong>: As mentioned, I am the author of the <a href="https://github.com/miile7/execdmscript" rel="nofollow noreferrer"><code>execdmscript</code></a> module. Still I think this is the best solution for this case. In fact this question was the reason I wrote the module.</p>
</blockquote>
<hr/>
<h2>基本数据类型</h2>
<p>对于<code>string</code>和<code>number</code>等基本数据类型,可以手动创建和添加代码。下面的例子说明了这个想法:</p>
<pre class="lang-py prettyprint-override"><code>import DigitalMicrograph as DM
import time
sync_id = "sync-{}".format(int(time.time() * 100))
dmscript = """
number input;
number s = GetNumber("Enter a number between {min} and {max}.", {init}, input);
TagGroup p = GetPersistentTagGroup();
p.TagGroupSetTagAsBoolean("{id}-success", s);
p.TagGroupSetTagAsLong("{id}-input", input);
"""
DM.ExecuteScriptString(dmscript.format(min=1, max=10, init=2, id=sync_id))
# cannot save TagGroups to variables, check below
s, success = DM.GetPersistentTagGroup().GetTagAsBoolean("{}-success".format(sync_id))
if s and success:
# cannot save TagGroups to variables, check below
s, input = DM.GetPersistentTagGroup().GetTagAsLong("{}-input".format(sync_id))
if s:
print(input)
else:
print("Did not find 'input' in persistent tags.")
elif not s:
print("Did not find 'success' in persistent tags.")
else:
print("User clicked cancel.")
# cannot save TagGroups to variables, check below
# delete tag, otherwise the persistent tags gets filled with garbage
DM.GetPersistentTagGroup().DeleteTagWithLabel("{}-success".format(sync_id))
DM.GetPersistentTagGroup().DeleteTagWithLabel("{}-input".format(sync_id))
</code></pre>
<p>正如人们所看到的,这种方法有一些缺点。有很多代码创建设置和同步,只需输入一个数字。这使得代码混乱不堪。还可以将dm脚本代码保存在一个单独的文件中,该文件添加了python文件打开。在此代码中调试dm脚本代码也很困难。最后,标记组在python端的移动也有一些限制(请查看下面的内容)</p>
<hr/>
<h2>局限性</h2>
<p><em>更新</em>:下面提到的python模块可以处理<code>TagGrou</code>和<code>TagList</code>,因为它将它们线性化并使用单独的键和类型保存</p>
<p>请注意<code>TagGroup</code>很难同步<code>TagGroup</code>不能分配给变量。一旦它们被使用,它们就不再可用。这可以通过以下非常简单的代码来说明:</p>
<pre class="lang-py prettyprint-override"><code>import DigitalMicrograph as DM
# create group for the example
group1 = DM.NewTagGroup()
group1.SetTagAsString("test-string", "test content")
print("Group 1 valid:", group1.IsValid(), "(type:", type(group1), ")")
# save to persistent tags
DM.GetPersistentTagGroup().SetTagAsTagGroup("test", group1)
# get the group without assigning to a variable, works
s, group2 = DM.GetPersistentTagGroup().GetTagAsTagGroup("test")
print("Group 2 success:", s, ", valid:", group2.IsValid(), "(type:", type(group2), ")")
# assign one parent group to a variable, doesn't work
tags = DM.GetPersistentTagGroup()
s, group3 = tags.GetTagAsTagGroup("test")
print("Group 3 success:", s, ", valid:", group3.IsValid(), "(type:", type(group3), ")")
</code></pre>
<p>此代码将生成输出</p>
<pre><code>Group 1 valid: True (type: <class 'DigitalMicrograph.Py_TagGroup'> )
Group 2 success: True , valid: True (type: <class 'DigitalMicrograph.Py_TagGroup'> )
Group 3 success: True , valid: False (type: <class 'DigitalMicrograph.Py_TagGroup'> )
</code></pre>
<p>这表明您不能将<code>TagGroup</code>分配给python变量</p>
<hr/>
<h2>异步思想</h2>
<p>这可以扩展到异步应用程序。<code>dm-script</code>和<code>python</code>实现可以设置观察持久标记的线程。(请注意,您可以使用<code>TagGroupMarkAsChanged()</code>将<code>TagGroup</code>标记为已修改),这两个标记完全不同。然后两者都可以向标记添加命令和/或数据。另一个“实例”可以读取和处理它们</p>
<p>这必须手动编码。这(目前)不包括在<code>execdmscript</code>模块中</p>