Parsing 为什么';这不是开始工作的用法吗?

Parsing 为什么';这不是开始工作的用法吗?,parsing,wolfram-mathematica,symbols,Parsing,Wolfram Mathematica,Symbols,如果我们逐个计算这些行,将在上下文cc中创建x Begin["cc`"]; x = 1; End[] 但是如果我们一起评估的话, (Begin["cc`"]; x = 1; End[]) 然后将在Global中创建x。尽管进行了以下打印cc`: (Begin["cc`"]; Print[$Context]; End[]) 这种行为的原因是什么?我猜上下文只在解析阶段起作用,而不是在评估阶段 用例:我想创建一个调色板按钮,在“私有”上下文中定义一些符号,以避免与全局符号冲突除了将所有定义放在

如果我们逐个计算这些行,将在上下文
cc
中创建
x

Begin["cc`"];
x = 1;
End[]
但是如果我们一起评估的话,

(Begin["cc`"];
x = 1;
End[])
然后将在
Global
中创建
x
。尽管进行了以下打印
cc`

(Begin["cc`"];
Print[$Context];
End[])
这种行为的原因是什么?我猜上下文只在解析阶段起作用,而不是在评估阶段

用例:我想创建一个调色板
按钮
,在“私有”上下文中定义一些符号,以避免与全局符号冲突除了将所有定义放在包文件中并从调色板加载外,执行此操作的首选方法是什么?(我想让调色板保持独立。)

符号(及其上下文)是在解析时创建的,而不是在求值时创建的。如果我们使用
$NewSymbol
,我们可以看到这一点:

$NewSymbol=Print["Name: ",#1," Context: ",#2]&;

Print["first"];
test1;
Print["last"]

(Print["first"];
 test2;
 Print["last"])
第一个打印:

first
Name: test1 Context: Global`
last
因为单元格中的每一行都被视为单独的输入。第二种方法使用括号强制将所有三行视为一个输入并打印

Name: test2 Context: Global`
first
last
从中我们可以看到,
test2
是在任何计算发生之前在
Global`
上下文中创建的


我认为最简单的方法是在符号上使用显式上下文:
cc`x=1

对于第二个问题,我建议您参考我的答案,它有效地自动化了您概述的步骤(使用
ParseTimeNameSpaceWrapper
函数)。它可能需要做更多的工作,使其更加健壮,但这可能是一个起点。我偶尔也会用这种东西

仅供参考:

(Begin["cc`"]; Evaluate[Symbol["x"]] = 1; End[])

cc`x

我刚刚在文档中读到“符号名称的解释取决于上下文。
Begin
因此会影响输入表达式的解析。”这回答了我的第一个问题。第二个仍然有效。
ParseTimeNameSpaceWrapper
仍然没有回避这样一个事实,即符号的上下文是在解析时决定的,即如果我做了
ParseTimeNameSpaceWrapper[x]
,那么
x
仍将被解释为
Global`x
,而不是
MyLocalizedContext`x
。在理解了上下文是在解析时选择的之后,我认为除了通过将一些代码放入字符串并使用
ToExpression
,或者从包中读取它(或者只是按照Brett的建议显式地编写上下文,但对于较长的代码来说,这是一个很大的工作)来强制重新解析之外,没有其他方法了。关于解析阶段,您可能对这个线程感兴趣:另一个有时有用的选项是在求值期间使用ToExpression进行一些新的解析:(Begin[“cc`]”;With[{s=ToExpression[“x”]},s=1];End[];)Brett,是否有任何方法可以使用
$NewSymbol
强制在特定上下文中创建符号,并且扩展为不在默认上下文中创建符号?@Andrew,为什么不将其作为答案发布?@Mr.Wizard可能没有,因为
$NewSymbol
不会影响进一步评估期间该符号的情况。我在做一些类似于@Andrew所说的事情。当使用显式上下文名称变得麻烦时,可以将所有内容都放在.m文件中并读取该文件。使调色板自包含的方法可能是使用一个巨大的字符串而不是.m文件,并从中读取。除非有可靠的笔记本/前端向导将代码包含在调色板笔记本中,并在加载调色板时评估定义。@Mr.Wizard我想这应该是一个单独的问题。我对笔记本电脑和前端没有太多经验。
1