一个在C#中集成Python的例子。在C#中可以执行Python脚本,在Python中也可以调用C#宿主中的功能(clr.AddReference('Business'))。
文件说明
Debug为执行目录
Mgr.exe为执行文件
Py\init.py为python初始化脚本
Py\Lib.zip为python需要的模块,可以在init.py中import
Data为数据库目录
mgr.db为mgr.exe使用的数据库
操作说明
系统设置
可以在这里修改运行的参数
打开一个账户
用户的规则设置
交易
代码说明
Python的说明
在Python中可以调用C#宿主中的功能(clr.AddReference('Business'))。
import clr
import io
import os
import string
clr.AddReference('System')
clr.AddReference('System.Data')
clr.AddReference('Business')
from System import *
from System.Data import *
from Business import *
def get_account_money_by_dt(account_id,date):
db=Pub.db_name_mgr
InitMoney=Pub.select_str(db,"select InitMoney from account where account_id="+account_id)
cash=Pub.select_str(db,"select sum(amount_real) from tran where account_id="+account_id+" and tran_date<="+date)
stock_amount=float.Parse("0")
table_stock=Pub.select(db,"select code_type,code,sum(tran_count_real) as c from tran where account_id="+account_id+" and code<>'' and tran_date<="+date +" group by code_type,code")
for dr in table_stock.Rows:
code_type=DBUtils.get_str(dr, "code_type");
code=DBUtils.get_str(dr, "code");
count=DBUtils.get_str(dr, "c");
price=Pub.select_str(code_type+"\\"+code,"select close from data_day where dt<="+date+" order by dt desc limit 1")
if price<>'':
stock_amount=stock_amount+float.Parse(price)*float.Parse(count)
if cash=="":
cash="0"
if InitMoney=="":
InitMoney="0"
return (float.Parse(InitMoney)+float.Parse(cash)+stock_amount).ToString("0.00")
C#的说明
加载Python环境
instance = new Py();
instance.init_py_lib();
public void init_py_lib()
{
engine = IronPython.Hosting.Python.CreateEngine();
scope = engine.CreateScope();
engine.Runtime.IO.SetOutput(Output,Encoding.Unicode);
engine.SetTrace(on_trace);
StringBuilder sb = new StringBuilder();
sb.AppendLine(@"import sys ");
sb.AppendLine(@"sys.path.append("".\py\Lib.zip"") ");
sb.AppendLine(@"sys.path.append("".\scripts"") ");
ScriptSource source = engine.CreateScriptSourceFromString(sb.ToString());
source.Execute(scope);
string init_py = Pub.exe_dir + @"\py\init.py";
if (System.IO.File.Exists(init_py))
{
ScriptSource source_init = engine.CreateScriptSourceFromFile(init_py);
source_init.Execute(scope);
}
}
执行脚本
public Boolean Execute(string script, out string msg, out IronPyErrors err, ExecRequest request)
{
msg = "";
err = new IronPyErrors();
StringBuilder sb = request.log;
sb.AppendLine("开始 "+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") );
sb.AppendLine("------");
try
{
last_trace_lineno = "";
last_trace_result = "";
ScriptSource source = engine.CreateScriptSourceFromString(script);
CompiledCode cc = source.Compile(err);
if (err.Items.Count > 0)
{
err.ToStringBuilder(sb);
msg = "编译错误";
sb.Append(msg);
return false;
}
scope.SetVariable("request", request);
Py.instance.Output.SetLength(0);
string sql_err = DataAccess.DataConn.clear_err();
cc.Execute(scope);
Py.instance.Output.Flush();
string print_s = Encoding.Unicode.GetString(Py.instance.Output.ToArray());
sql_err = DataAccess.DataConn.clear_err();
if (sql_err != "")
sb.AppendLine(sql_err);
sb.AppendLine(print_s);
sb.AppendLine("------");
msg = "运行完成 "+ DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") ;
sb.Append(msg);
return true;
}
catch (Exception e)
{
if (last_trace_lineno != "")
msg = "trace line:" + last_trace_lineno;
if (last_trace_result != "")
msg = msg + " " + "trace:" + last_trace_result;
msg = msg + " " + e.Message;
sb.Append(msg);
}
return false;
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using IronPython;
using IronPython.Runtime;
using IronPython.Modules;
using IronPython.Compiler;
using IronPython.Runtime.Exceptions;
using IronPython.Hosting;
using Business;
namespace Mgr
{
public class Py
{
public static Py instance = null;
public static void init()
{
if (instance != null)
return;
instance = new Py();
instance.init_py_lib();
}
public ScriptEngine engine = null;
public ScriptScope scope = null;
public static string get_key(string name)
{
return name.Trim().ToLower();
}
public static Dictionary<string , ScriptSource> ScriptDict = new Dictionary<string , ScriptSource>();
public string set_script(string id ,string script)
{
if (id == "")
id = Guid.NewGuid().ToString();
id = get_key(id);
ScriptSource source = engine.CreateScriptSourceFromString(script);
ScriptDict[id] = source;
return id;
}
public string last_trace_lineno = "";
public string last_trace_result = "";
public TracebackDelegate on_trace(TraceBackFrame frame, string result, object payload)
{
last_trace_lineno = frame.f_lineno.ToString();
last_trace_result = result;
return on_trace;
}
public Boolean Compile(string script,out string msg, out CompiledCode cc, out IronPyErrors err)
{
msg = "";
err = new IronPyErrors();
cc = null;
try
{
ScriptSource source = engine.CreateScriptSourceFromString(script);
cc = source.Compile(err);
msg = "编译完成";
return true;
}
catch (Exception e)
{
msg = e.Message;
}
return false;
}
public Boolean Execute_cc(CompiledCode cc, out string msg, ExecRequest request)
{
msg = "";
StringBuilder sb = request.log;
sb.AppendLine("开始 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
sb.AppendLine("------");
try
{
last_trace_lineno = "";
last_trace_result = "";
scope.SetVariable("request", request);
Py.instance.Output.SetLength(0);
string sql_err = DataAccess.DataConn.clear_err();
cc.Execute(scope);
Py.instance.Output.Flush();
string print_s = Encoding.Unicode.GetString(Py.instance.Output.ToArray());
sql_err = DataAccess.DataConn.clear_err();
if (sql_err != "")
sb.AppendLine(sql_err);
sb.AppendLine(print_s);
sb.AppendLine("------");
msg = "运行完成 " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
sb.Append(msg);
return true;
}
catch (Exception e)
{
if (last_trace_lineno != "")
msg = "trace line:" + last_trace_lineno;
if (last_trace_result != "")
msg = msg + " " + "trace:" + last_trace_result;
msg = msg + " " + e.Message;
sb.Append(msg);
}
return false;
}
public Boolean Execute(string script, out string msg, out IronPyErrors err, ExecRequest request)
{
msg = "";
err = new IronPyErrors();
StringBuilder sb = request.log;
sb.AppendLine("开始 "+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") );
sb.AppendLine("------");
try
{
last_trace_lineno = "";
last_trace_result = "";
ScriptSource source = engine.CreateScriptSourceFromString(script);
CompiledCode cc = source.Compile(err);
if (err.Items.Count > 0)
{
err.ToStringBuilder(sb);
msg = "编译错误";
sb.Append(msg);
return false;
}
scope.SetVariable("request", request);
Py.instance.Output.SetLength(0);
string sql_err = DataAccess.DataConn.clear_err();
cc.Execute(scope);
Py.instance.Output.Flush();
string print_s = Encoding.Unicode.GetString(Py.instance.Output.ToArray());
sql_err = DataAccess.DataConn.clear_err();
if (sql_err != "")
sb.AppendLine(sql_err);
sb.AppendLine(print_s);
sb.AppendLine("------");
msg = "运行完成 "+ DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") ;
sb.Append(msg);
return true;
}
catch (Exception e)
{
if (last_trace_lineno != "")
msg = "trace line:" + last_trace_lineno;
if (last_trace_result != "")
msg = msg + " " + "trace:" + last_trace_result;
msg = msg + " " + e.Message;
sb.Append(msg);
}
return false;
}
public MemoryStream Output = new MemoryStream();
public void init_py_lib()
{
engine = IronPython.Hosting.Python.CreateEngine();
scope = engine.CreateScope();
engine.Runtime.IO.SetOutput(Output,Encoding.Unicode);
engine.SetTrace(on_trace);
StringBuilder sb = new StringBuilder();
sb.AppendLine(@"import sys ");
sb.AppendLine(@"sys.path.append("".\py\Lib.zip"") ");
sb.AppendLine(@"sys.path.append("".\scripts"") ");
ScriptSource source = engine.CreateScriptSourceFromString(sb.ToString());
source.Execute(scope);
string init_py = Pub.exe_dir + @"\py\init.py";
if (System.IO.File.Exists(init_py))
{
ScriptSource source_init = engine.CreateScriptSourceFromFile(init_py);
source_init.Execute(scope);
}
}
}
public class IronPyErrorsItem
{
public string Message { get; set; }
public int ErrorCode { get; set; }
public Severity sev { get; set; }
public SourceSpan Span { get; set; }
public string get_info()
{
string line = "";
line = Span.Start.Line.ToString() + "行" + Span.Start.Column.ToString() + "列";
line = line + "(" + sev.ToString() +" " + ErrorCode.ToString()+"): ";
line = line + Message;
return line;
}
}
public class IronPyErrors : ErrorListener
{
public List<IronPyErrorsItem> Items = new List<IronPyErrorsItem>();
public void ToStringBuilder(StringBuilder sb)
{
foreach (IronPyErrorsItem i in Items)
{
sb.AppendLine(i.get_info());
}
}
public override void ErrorReported(ScriptSource source, string message, Microsoft.Scripting.SourceSpan span, int errorCode, Microsoft.Scripting.Severity severity)
{
IronPyErrorsItem i = new IronPyErrorsItem{
Message = message,
ErrorCode = errorCode,
sev = severity,
Span = span
};
Items.Add(i);
}
}
}