Python for .NETは各種の環境へインストールが可能となっていますが、どの組み合わせで可能なのか今一歩情報がまとまっていません。
やってみて出来たものを中心にまとめていこうと思います。
できたものから順に記述していこうと思います。
あ、使い方はPython -> .NET方向の呼び出しのみで、Embedded Scripting(.NET -> Python)は使っていません。
共通項目
環境ごとにチェックしていますが、共通事項をここに書いておきます。
Pythonnetのインストール
本家にインストールガイドがあります。
###PyPI
pip install pythonnet
PyPIリポジトリはこちら: https://pypi.python.org/pypi/pythonnet. Windows用のWheelもここにあります。
Anaconda
conda install -c pythonnet pythonnet
conda install -c conda-forge pythonnet
Anacondaリポジトリはこちら: https://anaconda.org/pythonnet/pythonnet
github
pip install git+https://github.com/pythonnet/pythonnet
または、
git clone https://github.com/pythonnet/pythonnet
pip install .
nuget
PM> Install-Package pythonnet -Version 3.0.0-preview2021-10-05
こちらにNuGetリポジトリがあります https://www.nuget.org/packages/pythonnet/
Windows 10
これを使うのは、Windows 10での動作がメインと思いますので、厚めに試します。
固定条件として以下とします。
- pythonnet 最新版 (2.4.0)
- Anaconda python 3.x
には、以下のように書いてあるので、基本的に、3.7を使っています。
Python 3.8.0 support
Some features are disabled in Python 3.8.0 because of this bug in Python. The error is System.EntryPointNotFoundException : Unable to find an entry point named 'Py_CompileString' in DLL 'python38'. This will be fixed in Python 3.8.1.
.NET Framework 4 (成功)
早く.NET5が出てほしいところですが、もうしばらく待たないといけないので、レガシーの方から。Windows10にプリインストールの.NET 4.6を利用しています。
.NET環境の準備
特に何もしなくてよさそうです。標準の環境ですから当たりまえですね。
Python環境の準備
これもAnaconda3の環境を入れただけで、特にTweakは必要なかったです。
やり方は共通項目参照。
動作確認
これでエラーが出なければ、ひとまず大丈夫でしょう。
import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import Form
import sys
print("OS : ", Environment.OSVersion.VersionString)
print("Python : " ,sys.version)
print(".NET : ", Environment.Version.ToString())
print("pythonnet : " , clr.__version__)
OS : Microsoft Windows NT 10.0.19041.0
python : 3.7.3 (default, Apr 24 2019, 15:29:51) [MSC v.1915 64 bit (AMD64)]
.NET : 4.0.30319.42000
pythonnet : 2.4.0
Windows 10のバージョンが怪しいですが、そこは。。。
.NET Standard ライブラリの呼び出し (成功)
BayesServerの最新版8.xから、.NET Standardでの提供になったことがあり、Python for .NET(.NET Framework) ->.NET Standardライブラリの呼び出しを検証しました。
sys.path.append("C:/Program Files/Bayes Server/Bayes Server 8.16/API/DotNet/Standard20/")
clr.AddReference("BayesServer")
import BayesServer
network = Network()
network.Load("model.bayes")
print(network.Links.Count)
.NET Core
デスクトップ開発者もそろそろ .NET Coreに移行を考えてもいいんじゃないかというレベルに来ているのかどうか知りませんが、.NET Core 3.1でFrameworkに劣らない機能が利用できるようになっています。
しかし、残念ながらpythonnetではまだ準備ができておらず、.NET CoreからPythonを動かそうという事はできないようです。(そもそも、そんな事許されるわけないじゃん)
Support for .NET Core? #243 @ github
.NET Core (CoreCLR) does not provide reverse pinvoke like .NET Framework on
Windows, neither C++/CLI. Hence the only way to get this working is to
embed .NET Core using C-API, like this is done for Mono. The problem is
that C-API for CoreCLR looks quite different from Mono.
CoreCLRではreverse P/Invokeがサポートされていないから、無理ゲーと書いています。
Pythonから.NET Coreは出来てもいいんじゃない?と思いますが。
しかし!上記は2016年の情報で、そこから以下のissueに状況が記されています。
.NET Core support and CoreCLR embedding - cross-platform API #96 @ github
denfromufa commented on Oct 17, 2018
によると、以下のサポート状況のようです。
Platform | .NET-> Python | Python -> .NET |
---|---|---|
Windows | Tested | Coded (npython.exe) |
Linux | Tested | Tested (npython.exe) |
OSX | Coded | Coded (npython.exe) |
Pythonから.NET Coreを呼ぶ場合は、npython限定など、かなり制限がきついようですね。
Linux
Linux上ではMonoを対象としたブリッジとして作動します。
Mono-Amazon Linux
Sagemakerで使おうとして、普通にpipやcondaではインストールがうまくいかなかったのですが、どうやら以下でうまくいくようです。
source activate python3
conda install -c conda-forge/label/cf202003 pythonnet
Sagemakerのノートブックインスタンスでデフォルトで使われるEC2インスタンスは、以下が割り当てられます。
OS : Amazon Linux AMI release 2018.03 64bit
Conda : 4.8.4
Python : 3.6.13
最近Amazon Linux 2というのが出たようですが、まだデフォルトになっていないようです。
OS : Amazon Linux release 2 (Karoo) 64bit
Conda : 4.8.4
Python : 3.6.13
基本的にAL1,AL2とも同じ挙動のようでした。
失敗例
素の状態からpipインストールをしようとすると
pip install pythonnet
...
/bin/sh: mono: command not found
...
monoに起因するようなエラーでインストールが失敗します。(類似エラー)
condaでインストールするとインストールは環境するのですが、
conda install -c pythonnet pythonnet
...
Executing transaction: done
以下のようにimport clrでmono libraryが見当たらないとなります。リンクエラーですかね。(類似エラー)
import clr
...
System.DllNotFoundException: /home/ec2-user/anaconda3/envs/python3/lib/../lib/libmono-native.so assembly:<unknown assembly>
...
結局SageMaker上というか、monoインストールをcondaに任せる場合、上記のラベルなどを指定しないとうまくいかないという事だと思います。
Mono-Ubuntu
以下でMonoをインストールします。これでほぼ実行環境は準備完了。
sudo apt-get install mono-complete
同じ要領でpythonnet を読み込んでチェックします。
import clr
clr.AddReference("System.Windows.Forms")
from System.Windows.Forms import Form
Ubuntu 16.04.6 LTS上の環境を使っています。
import sys
print("OS : ", Environment.OSVersion.VersionString)
print("python : " ,sys.version)
print(".NET : ", Environment.Version.ToString())
print("pythonnet : " , clr.__version__)
OS : Unix 4.15.0.1063
python : 3.6.9 |Anaconda, Inc.| (default, Jul 30 2019, 19:07:31)
[GCC 7.3.0]
.NET : 4.0.30319.42000
pythonnet : 2.4.0
.NET Standard ライブラリの呼び出し (成功)
Python for .NET(Mono) ->.NET Standard.NET Standardライブラリの呼び出しを検証しました。
sys.path.append("/mnt/azmnt/code/Users/bayesserver-8.16/DotNet/Standard20")
clr.AddReference("BayesServer")
import BayesServer
network = Network()
network.Load("model.bayes")
print(network.Links.Count)
どうにか動いているようです。