PythonとD

こんにちは、Habr!

ここでは、言語の長所と短所については説明しません。



それらを一緒に使用します!



素晴らしいpydライブラリがこれを助けてくれます。 その助けを借りて、dコードからpythonコードを呼び出すことも、その逆も可能です。

最初のオプションを検討してください。 dub.jsonファイルに入力します。

{ "name": "pydtest", "targetType": "executable", "dependencies": { "pyd": "~>0.9.7" }, "subConfigurations": { "pyd": "python34" } } 

subConfigurationsは、Python 3.4を使用することを示します

source / main.dを作成します。

 import std.stdio; import pyd.pyd, pyd.embedded; void main() { py_init(); auto script = new InterpContext; //  2        //        myscript.py   script.py_stmts( "import sys" ); script.py_stmts( "sys.path.append('.')" ); script.py_stmts( "import myscript" ); writeln( script.py_eval!string( "myscript.func()" ) ~ " from pyd" ); } 

myscript.pyを作成します
 def func(): return "hello habr!" 

アセンブリとその結果を開始します
 dub build && ./pydtest 

それだけです!
 hello habr! from pyd 

すべてがとてもシンプルです!

少し複雑にしてみましょう。 myscript.pyに数字を追加する機能を追加します。

 def sum(a,b): return a + b 

Dのコードから呼び出します。これをmain.main関数に追加します。

 ... script.x = 13; script.y = 21; writefln( "result: %d", script.py_eval!int( "myscript.sum(x,y)" ) ); ... 

複雑に失敗しました。

InterpContextクラスはインタープリターのコンテキストを表し(奇妙なことに)、そのような簡単な方法で変数を追加できます。 フィールドxとyはスクリプトオブジェクトの一部ではありません-そのようなフィールドはありませんが、D言語ではクラス(または構造体)の存在しないメソッドへの呼び出しをopDispatchメソッドへの呼び出しに変換できるため、これは機能します。

InterpContext.opDispatchメソッドコード
  @property PydObject opDispatch(string id)() { //     return this.locals[id]; } @property void opDispatch(string id, T)(T t) { //     static if(is(T == PydObject)) { alias ts; }else{ PydObject s = py(t); } this.locals[id] = py(s); } 


同様に、コンテキストからオブジェクトを取得できます。

 ... script.py_stmts( "z = myscript.sum(8,7)" ); writefln( "result2: %d", script.z.to_d!int ); ... 

そして、ほぼ同じ方法で関数を呼び出すことができます:

 ... auto sum = script.myscript.sum; writefln( "result3: %d", sum(14,15).to_d!int ); ... 

いくつかのポイント
D言語のプロパティ構文は長い間議論されトピックであり、具体的には、プロパティがopCallメソッドでオブジェクトを返すときの状況に関連しています。

 script.myscript.sum(14,15).to_d!int; // ,  ,     script.myscript.oneargfunc(12).to_d!int; //  ,   oneargfunc(12)   opDispatch   12 script.myscript.oneargfunc()(12).to_d!int; //    :   oneargfunc(),     opCall(12) 


次に、Pythonコードから別の方法でDのコードを呼び出してみましょう。このための新しいフォルダーを作成します。
内容を含むdcode.dファイルを作成します。

 module dcode; import pyd.pyd; import std.math; float[] calc( float x, float y ) { return [ sqrt(x*y), x^^y, x/y ]; } extern(C) void PydMain() { def!(calc)(); module_init(); } 

そして、setup_my_dcode.pyファイル(名前は影響しません):

 from pyd.support import setup, Extension projName = 'dcode' setup( name=projName, version='0.1', ext_modules=[ Extension(projName, ['dcode.d'], extra_compile_args=['-w'], build_deimos=True, d_lump=True ) ], ) 

拡張機能をビルドしましょう(テストファイルでシステムを詰まらせないように、インストールではなくビルドします)。

 python3 setup_my_dcode.py build 

そのようなコンテンツのパパビルドを作成する
 build ├── lib.linux-x86_64-3.4 │  └── dcode.cpython-34m.so └── temp.linux-x86_64-3.4 └── infra ├── pydmain.d ├── so_ctor.o └── temp.o 

build / lib.linux-x86_64-3.4 / dcode.cpython-34m.soに興味があります。 これを現在のディレクトリにコピーするか、それを含むフォルダーに移動し、インタラクティブインタープリターで直接確認できます。

 python3 Python 3.4.1 (default, Nov 3 2014, 14:38:10) [GCC 4.9.1 20140930 (Red Hat 4.9.1-11)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import dcode >>> dcode.calc( 5, 12 ) [7.745966911315918, 244140624.0, 0.4166666567325592] >>> 

また、すべてが非常に簡単です!

そして再び、すべてを複雑にしてみましょう-クラスをdcode.dに追加します:

 class Foo { float a = 0, b = 0; static string desc() { return "some ops"; } this( float A, float B ) { a = A; b = B; } float sum() const { return a + b; } float div() const { return a / b; } } extern(C) void PydMain() { def!(calc)(); //   module_init(); //    wrap_class!( //    Foo, Init!(float,float), Repr!(Foo.toString), //  python      Def!(Foo.sum), Def!(Foo.div), StaticDef!(Foo.desc) )(); } 

残念ながら、この状況では、事態は少し複雑になりました。 PythonでDクラスを使用するには、コンストラクター、関数などを宣言する必要があります。

収集、確認:

 python3 Python 3.4.1 (default, Nov 3 2014, 14:38:10) [GCC 4.9.1 20140930 (Red Hat 4.9.1-11)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from dcode import Foo >>> Foo.desc() 'some ops' >>> a = Foo(1,2) >>> a.div() 0.5 >>> a.sum() 3.0 >>> 

うまくいく!

アプリケーションのオプションについて話す必要はありません。多くのオプションがあり、興味深いものです。 ライブラリがまだ安定バージョン1.0.0に達していないため、エラーが発生する可能性があることに注意してください。

私は1つの問題だけを見つけました:Dコードに埋め込まれたPythonコードからDコードを実行することはできません:



しかし、これは根本的な問題ではなく、著者が簡単に修正できるように思えます。

非常に素晴らしいプロジェクトのドキュメントがここにあり、他の例がここにあります

Source: https://habr.com/ru/post/J259727/


All Articles