【问题标题】:Checking if a symbol is defined检查是否定义了符号
【发布时间】:2011-06-03 17:02:17
【问题描述】:

有没有简单的方法来检查 x 是否有定义?我需要一个功能 f,f[_]f[_][_] 的形式,如果有定义则返回 True

具体来说,我使用 f[x]=b 和 g[x][y]=z 之类的结构来存储东西,我需要检查 f[x] 是否对某些中的每个 x 都有定义列表,如果 g[x][y] 对某些值集中的每个 x,y 都有定义

【问题讨论】:

    标签: wolfram-mathematica


    【解决方案1】:
    • 对于 System` 中的符号,请检查 SyntaxInformation 中的 ArgumentsPattern 选项。
    • 对于其他符号,请检查 DownValues、UpValues、SubValues 等...

    预期用途是什么?

    【讨论】:

    • 我有一个函数,如果我在缺少某些定义时运行它会产生大量错误,所以我想添加自动检查以中止并按照“错误,xyz [] [] 未定义”
    • DownValues 帮助我检查了一个函数是否已定义,ValueQ 对此不起作用——或者如果调用为 ValueQ[myFunc[x]] 将评估该函数。
    【解决方案2】:

    如果我理解正确,我认为函数ValueQ 就是您正在寻找的。如果变量或函数已定义,则返回 true;如果尚未定义,则返回 false。

    阅读更多http://reference.wolfram.com/mathematica/ref/ValueQ.html

    【讨论】:

      【解决方案3】:

      实际上,ValueQ 函数并不是无辜的,因为它会泄漏对具有副作用的代码的评估。例子:

      ClearAll[f, g]; 
      f[x_] := Print[x]; 
      g[x_][0] := Print[x];
      {ValueQ[f[1]],ValueQ[g[2][0]]}
      

      如果您删除 ValueQ 的 ReadProtected 属性并查看代码,您会明白原因 - 代码非常简单,并且仅对 OwnValues 做得不错。这是我为避免此问题而开发的一个更复杂的版本(您可以测试,至少对于上面的示例,它不会泄漏评估):

      ClearAll[symbolicHead];
      SetAttributes[symbolicHead, HoldAllComplete];
      symbolicHead[f_Symbol[___]] := f;
      symbolicHead[f_[___]] := symbolicHead[f];
      symbolicHead[f_] := Head[Unevaluated[f]];
      
      ClearAll[partialEval];
      SetAttributes[partialEval, HoldAllComplete];
      partialEval[a_Symbol] /; OwnValues[a] =!= {} := 
         Unevaluated[partialEval[a]] /. OwnValues[a];
      
      partialEval[a : f_Symbol[___]] /; DownValues[f] =!= {} :=
         With[{dv = DownValues[f]},
            With[{eval = Hold[partialEval[a]] /. dv},
               ReleaseHold[eval] /; 
                 (First[Extract[eval, {{1, 1}}, HoldComplete]] =!= 
                 HoldComplete[a])]];
      
      partialEval[a_] :=
         With[{sub = SubValues[Evaluate[symbolicHead[a]]]},
            With[{eval = Hold[partialEval[a]] /. sub},
               ReleaseHold[eval] /; 
                 (First[Extract[eval, {{1, 1}}, HoldComplete]] =!= 
                 HoldComplete[a])]];
      
      ClearAll[valueQ];
      SetAttributes[valueQ, HoldAllComplete];
      valueQ[expr_] := partialEval[expr] =!= Unevaluated[partialEval[expr]];
      

      这也不完整,因为它没有考虑 UpValues、NValues 和 FormatValues,但这似乎足以满足您声明的需求,而且,这三种额外情况的规则也许也可以同时添加行如上。

      【讨论】:

      • 我认为 ValueQ 适合我,因为我使用 f[] 和 f[][] 作为字典来存储常量,但如果出现更一般的需求,我会记住这个秘诀,谢谢
      【解决方案4】:

      如果所讨论的对象具有足够的内部结构,这是一个很好的简单解决方案。

      你可以使用

      Length[variable]
      

      检测variable 是否已分配给具有多个部分的事物。因此:

      Remove[variable]
      Length[variable]
      (*---> 0*)
      variable={1,2,3};
      Length[variable]
      (*---> 3*)
      

      在后一种情况下,您可以使用Length[variable]>0 获取True

      但是,如果有可能将 variable 分配给一个原子值,例如单个字符串或数字,这将失败:

      variable=1
      Length[variable]
      (*---> 0*)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-28
        • 2010-09-22
        • 2017-11-16
        • 2015-05-01
        • 1970-01-01
        相关资源
        最近更新 更多