web-dev-qa-db-ja.com

Juliaにカスタムモジュールをインポートする方法

ここに書いたモジュールがあります:

# Hello.jl
module Hello
    function foo
        return 1
    end
end

そして

# Main.jl
using Hello
foo()

Mainモジュールを実行すると:

$ Julia ./Main.jl

私はこのエラーを受け取ります:

ERROR: LoadError: ArgumentError: Hello not found in path
 in require at ./loading.jl:249
 in include at ./boot.jl:261
 in include_from_node1 at ./loading.jl:320
 in process_options at ./client.jl:280
 in _start at ./client.jl:378
while loading /Main.jl, in expression starting on line 1
23
dopatraman

_using Hello_の前にinclude("./Hello.jl")する必要があります

12
张实唯

Julia v0.7およびv1.0のリリース以降、この質問に対する新しい回答がありますが、これは若干異なります。私はこれをしなければならなかったので、ここに私の調査結果を投稿すると思いました。

他のソリューションで既に説明したように、モジュールを定義する関連スクリプトを含める必要があります。ただし、カスタムモジュールはパッケージではないため、古いJuliaバージョンで実行できたのと同じusingまたはimportコマンドを使用してパッケージとしてロードすることはできません。

したがって、Main.jlスクリプトは、次のような相対インポートで記述されます。

include("./Hello.jl")
using .Hello
foo()

これは、同様の質問について Stefan Karpinskiの談話コメント で簡単に説明されています。彼が説明するように、サブモジュールを扱う場合、状況はより複雑になる可能性もあります。 モジュールパスのドキュメントセクション も参考になります。

28
kiliantics

すでにいくつかの短い回答がありましたが、可能であればより完全な回答を提供したかったのです。

using MyModuleを実行すると、JuliaはLOAD_PATHと呼ばれるディレクトリのリストでのみ検索します。 Julia REPLにLOAD_PATHと入力すると、次のようなメッセージが表示されます。

2-element Array{ByteString,1}:
 "/Applications/Julia-0.4.5.app/Contents/Resources/Julia/local/share/Julia/site/v0.4"
 "/Applications/Julia-0.4.5.app/Contents/Resources/Julia/share/Julia/site/v0.4"

これらは、using Helloと入力したときにJuliaが含めるモジュールを検索するディレクトリです。提供した例では、HelloLOAD_PATHにないため、ジュリアはそれを見つけることができませんでした。

ローカルモジュールを含める場合は、現在の作業ディレクトリに対する相対位置を指定できます。

Julia> include("./src/Hello.jl")

ファイルをインクルードしたら、using Helloを通常どおり実行して、同じ動作をすべて取得できます。 1回限りのスクリプトの場合、これがおそらく最良のソリューションです。ただし、特定のディレクトリセットを定期的にinclude()する必要がある場合は、LOAD_PATHに永続的に追加できます。

LOAD_PATHへのディレクトリの追加

Julia LOAD_PATHの外部に保存されている特定のモジュールを定期的に使用する場合は、LOAD_PATHに手動でディレクトリを追加するのは面倒です。その場合、LOAD_PATH環境変数に追加のディレクトリを追加できます。 Juliaは、importまたはusingコマンドを発行するたびに、これらのディレクトリを自動的に検索します。

これを行う1つの方法は、次を.basrc.profile.zshrcに追加することです。

export Julia_LOAD_PATH="/path/to/module/storage/folder"

これにより、Juliaが検索する標準ディレクトリにそのディレクトリが追加されます。次に実行する場合

Julia> LOAD_PATH

戻るはずです

3-element Array{ByteString,1}:
 "/path/to/module/storage/folder"
 "/Applications/Julia-0.4.5.app/Contents/Resources/Julia/local/share/Julia/site/v0.4"
 "/Applications/Julia-0.4.5.app/Contents/Resources/Julia/share/Julia/site/v0.4"

using Helloを自由に実行できるようになり、Juliaは/path/to/module/storage/folderの下に保存されている限り、モジュールを自動的に検出します。

詳細については、Julia Docsの this ページをご覧ください。

16
Remy Prechelt

张实唯の答えが最も便利ですが、REPLの外部でincludeを使用しないでください。プログラムファイルを作成している場合は、適切なディレクトリをLOAD_PATHに追加するというトラブルを経験してください。 Remyはその方法について非常に良い説明をしていますが、そもそもなぜそうする必要があるのか​​を説明する価値もあります。 (さらにドキュメント:Push!(LOAD_PATH, "/Path/To/My/Module/")からですが、モジュールとファイルは同じ名前でなければならないことに注意してください)

問題は、あなたがincludeを呼び出す場所で、includeが定義されていてもどこでも定義されている場合であることです。モジュールの目的は再利用であるため、最終的には複数のファイルでMyModuleを使用することになります。各ファイルでincludeを呼び出すと、それぞれがMyModuleの独自の定義を持ち、それらが同一であっても、これらは異なる定義になります。つまり、MyModuleで定義されているデータ(データ型など)は同じではありません。

これが大きな問題である理由を確認するには、次の3つのファイルを検討してください。

types.jl

_module TypeModule
struct A end
export A
end
_

a_function.jl

_include("types.jl")
module AFunctionModule
using TypeModule
function takes_a(a::A)
    println("Took A!")
end
export takes_a
end
_

function_caller.jl

_include("a_function.jl")
include("types.jl")
using TypeModule, AFunctionModule
my_a = A()
takes_a(my_a)
_

_Julia function_caller.jl_を実行すると、MethodError: no method matching takes_a(::TypeModule.A)が得られます。これは、function_caller.jlで使用されるタイプAがa_function.jlで使用されるタイプと異なるためです。この単純なケースでは、function_caller.jlのインクルードの順序を逆にすることで(または単にfunction_caller.jlからinclude("types.jl")を完全に削除することで、問題を「修正」できます!それは良くありません!)。しかし、TypeModuleで定義されている型も使用する別のファイルb_function.jlが必要な場合はどうでしょうか。あなたは何か非常にハックする必要があります。または、LOAD_PATHを変更して、モジュールが1回だけ定義されるようにすることもできます。

Xjiに応じて編集:モジュールを配布するには、Pkgdocs )を使用します。この質問の前提は、カスタムの個人的なモジュールであると理解しました。

ちなみに、ロードパスを変更するというアイデアが本当に好きではない場合(単一のスクリプトのスコープ内にある場合でも...)、モジュールをパッケージディレクトリにシンボリックリンクできます(たとえば_~/.Julia/v0.6/MyModule/MyModule.jl_)および次にPkg.add(MyModule)してから、通常どおりインポートします。それはもう少し面倒だと思います。

10
Graham Smith

ファイルを明示的にロードしない限り(include("./Hello.jl"))、JuliaはLOAD_PATH変数で定義されたディレクトリでモジュールファイルを探します。

このページ を参照してください。

1
daycaster

「using」を使用してモジュールをインポートするときに関数fooにアクセスする場合は、モジュールのヘッダーに「export foo」を追加する必要があります。

0
Accumulator