在使用IronPython和C#时,是否可以在运行之前检查Python脚本的语法?
既然我解决了检查语法的问题,我就来详细讲讲我是怎么做到的。我会用我自己的实现作为例子。
首先,我用了什么,怎么用的呢?
我使用了IronPython自2.6版本以来就有的ast
模块(我用的是2.7.4(1))。这个ast
模块可以构建代码的抽象语法树(简称ast)。这个功能让我可以知道一个脚本的语法是否正确。也就是说,如果模块成功创建了树,就说明语法没问题;如果出现了异常,那就说明语法有问题。
我怎么实现的呢?
实现的过程并不是最简单的,但我得感谢Pawel Jasinski,我遇到的一些错误在他的帮助下很快就解决了。
我将讨论两部分代码。首先,我会讲讲我从C#代码调用的Python部分。
Python:
import System
import sys
sys.path.append(r"C:\Program Files (x86)\IronPython 2.7\Lib") #This reference was vital, without it I wouldn't be able to check any code because Ironpython would just mention "no module named 'ast' "
import ast #The ast module is loaded to check the script for any errors.
def syntaxcheck(fileurl): #The method that runs the parse, I call this method in my C# code and provide the URL directly from an openfiledialog event.
result = ast.parse(open(fileurl, 'r').read())
return result
需要注意几件事:
C:\Program Files (x86)\IronPython 2.7\Lib
这个路径可能会因为你使用的Windows版本和IronPython的安装方式不同而有所不同。这个地址是Windows 7 64位的默认安装位置。import ast
必须放在import sys
和path.append
之后。- 确保这个文件的语法是正确的,不过通常不会出错,因为代码根本不会运行。我使用的是Python Tools for Visual Studio 2.0(3),这个工具让创建Python文件变得简单多了,而且只需要安装Visual Studio就可以创建Python文件,不需要其他软件。
现在是C#代码(这是从打开文件对话框中获取的,因为我就是这样用的,但这并不意味着你不能在其他函数或方法中使用):
private void ofdPython_FileOk(object sender, CancelEventArgs e)
{
//I made use of a simple MessageBox to give the user an easy way to see what file was faulty. There are better methods to do this but I will not elaborate on this here.
String strErrorSummarization = "Due to (an) error(s) in the selected files, it is not possible to run the selected test cases.\nHere is the list that shows all files until the erroneous file:\n";
//We add all files we want to use to a list which we will later turn into an array.
listScripts.AddRange((string[])ofdPython.FileNames);
//Create the runtime that will run the script through the IronPython interpreter.
var ipy = Python.CreateRuntime();
//Convert list to array
string[] saScripts = listScripts.ToArray();
//Loop trough all selected files and check them for their syntax.
for (int i = 0; i < listScripts.ToArray().Length; i++)
{
try
{
//Set pythonscript to use as checker the location can be anything you want as long as the file is available when running this code
dynamic syntaxCheck = ipy.UseFile("c:\\psyntax.py");
syntaxCheck.syntaxcheck(saScripts[i]);
//Add a note to the string we made to tell the checked script is OK
strErrorSummarization += saScripts[i].ToString() + " ---> contains no errors.\n";
}
catch (Exception e)
{
strErrorSummarization += saScripts[i].ToString() + " ---> IS ERRONEOUS.\n\nAll loaded files have been dropped, please check the above file for syntax errors!";
//Empty the selected files list
listScripts.Clear();
//Show the list of checked files including the file which had an error. If there are any extra file with error behind the first one, they will not be seen since the checking stop after the first faulty file
MessageBox.Show(strErrorSummarization, "Error(s) found in the selected scripts", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
在C#代码中需要引用以下内容:
using IronPython.Hosting;
还需要引用以下内容:
Name Path
Microsoft.Scripting.dll C:\Program Files(x86)\IronPython 2.7\Microsoft.Scripting.dll
IronPython.Modules.dll C:\Program Files(x86)\IronPython 2.7\IronPython.Modules.dll
IronPython.dll C:\Program Files(x86)\IronPython 2.7\IronPython.dll
上面的代码有注释,解释了我在做什么以及为什么。如果有任何问题,随时问我 :-)
因为我的声望太低,无法添加额外的超链接,所以这里列出带有数字的()括号的链接:
(1): http://ironpython.codeplex.com/downloads/get/723206 ---> IronPython 2.7.4
(2): http://en.wikipedia.org/wiki/Abstract_syntax_tree ---> Info on AST
(3): https://pytools.codeplex.com/releases/view/103102 ---> Python Tools for Visual Studio 2.0
1 个回答
1
我在最开始提问的地方展示了我找到的解决办法。因为我自己解决了这个问题,并把解决方案发在这里,所以我可以说这就是问题的答案。再次感谢Pawel Jasinski!:-) 也要感谢Baikuriu给我提示,让我去检查AST模块。