C#/.Net有其语言方面的优势,Python在生态方面则完胜,尤其大数据分析等数据结构和框架,比如: DataFrame, Numpy等。
如果能将两者优点结合,有利于对于软件的开发工作。本文通过使用PythonNet这个框架,在C#控制台项目中调用Python包。提供使用步骤,常见问题+解决方案和参考资料等。
.NET 有不完善的DataFrame,也不存在Numpy这种成熟数据分析框架; 换句话说:量化分析必须使用Python。
但是希望使用.NET,比如: ASP.NET CORE + IIS作为主要框架和生产环境,方便单元测试,项目管理,部署,IOC等各项操作;
因此,瓶颈: 能否在C#项目中调用Python?
对于上图,举例说明方案B的优势。
在发生未经处理异常的场景下, 由于存在IIS层,比如:调用交易所API超时。 WebServer(IIS)会日志异常内容,并重新启动程序。
而方案A则会导致程序在操作系统中崩溃,直到手动重启项目。
很明显,方案A有可能引发不可挽回的损失。
0.1 下载Python
根据自己的操作系统位数,下载对应版本。
作者使用WINDOW 64 Bit系统,因此下载64位exe版本。
安装到路径: C:\Program Files\Python311
安装过程中注意添加Python 到 PATH
CMD 输入
path=%path%;C:\Program Files\Python311\
CMD
PYTHON
如果安装失败,说明需要把python.exe所在的路径手动添加到path中. 也可以删除python重新安装
0.1 使用VisualStudio新建Console项目,并使用Nuget Package Manager安装pythonnet包
using Python.Runtime;
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
string dllPath = @"C:\Program Files\Python311\python311.dll"; // 此处需要对应Python的安装路径
string pythonHomePath = @"C:\Program Files\Python311";
// 对应Python内的重要路径
string[] py_paths = {"DLLs", "lib", "lib\\site-packages", "lib\\site-packages\\win32"
, "lib\\site-packages\\win32\\lib", "lib\\site-packages\\Pythonwin" };
string pySearchPath = $"{pythonHomePath};";
foreach (string p in py_paths)
{
var tmpPath = Path.Combine(pythonHomePath, p);
pySearchPath += $"{tmpPath};";
}
// 此处解决BadPythonDllException报错
Runtime.PythonDLL = dllPath;
Environment.SetEnvironmentVariable("PYTHONNET_PYDLL", dllPath);
// 配置python环境搜索路径解决 PythonEngine.Initialize() 崩溃
PythonEngine.PythonHome = pythonHomePath;
PythonEngine.PythonPath = pySearchPath;
PythonEngine.Initialize();
using (Py.GIL())
{
dynamic np = Py.Import("numpy");
Console.WriteLine(np.cos(np.pi * 2));
dynamic sin = np.sin;
Console.WriteLine(sin(5));
double c = np.cos(5) + sin(5);
Console.WriteLine(c);
dynamic a = np.array(new List<float> { 1, 2, 3 });
Console.WriteLine(a.dtype);
dynamic b = np.array(new List<float> { 6, 5, 4 }, dtype: np.int32);
Console.WriteLine(b.dtype);
Console.WriteLine(a * b);
Console.ReadKey();
}
}
}
}
出现上图,说明运行成功。
1 如果提示找不到Numpy?
分析:numpy包未安装
解决方案:
VS中 -> Package Manager Console
pip install numpy
安装后重新运行
2 利用Pythonnet,让C#调用Python(C# call Python by pythonnet)
4 Numpy的报错问题: https://numpy.org/devdocs/user/troubleshooting-importerror.html
#English Version
C#/.Net has its advantages in language, while Python wins in terms of ecology, especially data structures and frameworks such as big data analysis, such as: DataFrame, Numpy, etc.
If the advantages of the two can be combined, it will be beneficial to the development of software. This article calls the Python package in the C# console project by using the PythonNet framework. Provide usage steps, common problems + solutions and reference materials, etc.
.NET has an imperfect DataFrame, and there is no mature data analysis framework such as Numpy; in other words: quantitative analysis must use Python.
But I hope to use .NET, such as: ASP.NET CORE + IIS as the main framework and production environment, which is convenient for unit testing, project management, deployment, IOC and other operations;
Therefore, the bottleneck: Can I call Python in a C# project?
For the figure above, give an example to illustrate the advantages of option B.
In the case of unhandled exceptions, due to the existence of the IIS layer, for example: calling the exchange API timed out. WebServer (IIS) will log the abnormal content and restart the program.
Option A will cause the program to crash in the operating system until the project is manually restarted.
Obviously, Option A may cause irreparable losses.
0.1 Download Python
Download the corresponding version according to the number of digits of your own operating system.
The author uses WINDOW 64 Bit system, so download the 64-bit exe version.
Target Path: C:\Program Files\Python311
Pay attention to adding Python to PATH during installation
CMD Input
path=%path%;C:\Program Files\Python311\
CMD
PYTHON
The following figure shows that the installation is smooth
If the installation fails, it means that the path where python.exe is located needs to be manually added to the path. You can also delete python and reinstall
0.1 Use VisualStudio to create a new Console project, and use Nuget Package Manager to install the pythonnet package
using Python.Runtime;
namespace ConsoleApp2
{
internal class Program
{
static void Main(string[] args)
{
string dllPath = @"C:\Program Files\Python311\python311.dll"; // 此处需要对应Python的安装路径
string pythonHomePath = @"C:\Program Files\Python311";
// 对应Python内的重要路径
string[] py_paths = {"DLLs", "lib", "lib\\site-packages", "lib\\site-packages\\win32"
, "lib\\site-packages\\win32\\lib", "lib\\site-packages\\Pythonwin" };
string pySearchPath = $"{pythonHomePath};";
foreach (string p in py_paths)
{
var tmpPath = Path.Combine(pythonHomePath, p);
pySearchPath += $"{tmpPath};";
}
// 此处解决BadPythonDllException报错
Runtime.PythonDLL = dllPath;
Environment.SetEnvironmentVariable("PYTHONNET_PYDLL", dllPath);
// 配置python环境搜索路径解决 PythonEngine.Initialize() 崩溃
PythonEngine.PythonHome = pythonHomePath;
PythonEngine.PythonPath = pySearchPath;
PythonEngine.Initialize();
using (Py.GIL())
{
dynamic np = Py.Import("numpy");
Console.WriteLine(np.cos(np.pi * 2));
dynamic sin = np.sin;
Console.WriteLine(sin(5));
double c = np.cos(5) + sin(5);
Console.WriteLine(c);
dynamic a = np.array(new List<float> { 1, 2, 3 });
Console.WriteLine(a.dtype);
dynamic b = np.array(new List<float> { 6, 5, 4 }, dtype: np.int32);
Console.WriteLine(b.dtype);
Console.WriteLine(a * b);
Console.ReadKey();
}
}
}
}
The above figure appears, indicating that the operation is successful.
1 Can not find module Numpy?
分析:numpy is not installed
Solution:
Visual stusio -> Package Manager Console
pip install numpy
Rerun after installation
2 利用Pythonnet,让C#调用Python(C# call Python by pythonnet)
4 Numpy的报错问题: https://numpy.org/devdocs/user/troubleshooting-importerror.html