Эквивалент слова «определенный» в системе Mathematica.
-
22-07-2019 - |
Вопрос
Мне нужна функция, которая принимает имя символа в виде строки и возвращает, определен ли уже этот символ.Функция ValueQ
близок, но возвращает False для имен функций.Кроме того, он принимает символы, а не строки.
Примеры:
defined["N"] --> True (predefined function N)
defined["x"] --> False
x = 7;
defined["x"] --> True (x is now defined)
defined["7"] --> True (7 is a number)
f[x_] := 2x
defined["f"] --> True (f has DownValues)
g[x_][y_] := x+y
defined["g"] --> True (g has SubValues)
ПС:Спасибо Pillsy за указание на необходимость проверки как DownValues, так и SubValues.
Решение 2
Я собрал это вместе, и это, кажется, работает:
defined[s_] := ToExpression["ValueQ[" <> s <> "]"] ||
Head@ToExpression[s] =!= Symbol ||
ToExpression["Attributes[" <> s <> "]"] =!= {} ||
ToExpression["DownValues[" <> s <> "]"] =!= {} ||
ToExpression["SubValues[" <> s <> "]"] =!= {}
Надеюсь, есть более красивое решение.
ПС:Спасибо Pillsy за указание на необходимость проверки как DownValues, так и SubValues.
Другие советы
Я думаю, что имена должны помочь:
Имена ["String"] дает список имен символов, которые соответствуют строке.
Если Names["foo"] возвращает {}, то для foo не должно быть определений, в противном случае он должен возвращать {"foo"}.Таким образом, ваша функция «определена» может быть выполнена как:
defined[str_] := Names[str] != {}
По крайней мере, для символов, потому что для «7» это не работает, поскольку 7 не является символом.Вы можете обработать этот случай отдельно, например, с помощью NumberQ.
Кроме того, вы можете использовать «Символ», чтобы создать символ из строки (полезно для автоматического создания символов), и «Определение», чтобы проверить определения символа.
Символ [«Имя»] относится к символу с указанным именем.
Определение [символ] печатает как определения, приведенные для символа.
РЕДАКТИРОВАТЬ:Лучше, чем смотреть на то, что возвращает Names, NameQ["name"] сообщает вам, существует ли данное имя.Тем не менее, это не говорит вам, имеет ли символ явное определение, просто оно было упомянуто.
Вы можете использовать DownValues
чтобы узнать, есть ли у вас «функции», связанные с символом.Это будет работать для таких определений, как
f[x_, y_] := x + y
или
g[3] = 72 * a;
Это не сработает для экзотических вещей, таких как
h[a_][b] = "gribble";
но большинство людей все равно не будут думать об этом как об определении функции.Если вы хотите проверить существование определения функции, вам необходимо преобразовать имя в выражение (и убедиться, что оно заключено в Hold
когда ты это сделаешь!).Вот достаточно надежная функция, которая проверяет оба DownValues
и SubValues
:
functionNameQ[name_String] :=
With[{ hSymbol = ToExpression[name, InputForm, Hold] },
MatchQ[hSymbol, Hold[_Symbol]] &&
((DownValues @@ hName) =!= {} || (SubValues @@ hName) =!= {})];
defined[str_] := Not[ToString[FullDefinition[str]] === ""]