반응형

줄리아 Julia의 모듈(module) 에 대해 다룹니다. 

 

2024. 01. 06  최초 작성




다음 사이트를 참고하고 ChatGPT의 도움을 받았습니다. 

https://techytok.com/lesson-modules/



Julia 개발 환경 구축은 다음 포스트를 참고하세요. 

 

Visual Studio Code 사용한 Julia 개발 환경만들기(Windows / Ubuntu / Macbook M1)

https://webnautes.tistory.com/2216 



Julia 강좌를 진행하고 있습니다.

 

Julia 강좌 1 - 변수와 데이터 타입

https://webnautes.tistory.com/2218 

 

Julia 강좌 2 - 함수, void function,  Optional positional arguments, Keyword arguments

https://webnautes.tistory.com/2220 

 

Julia 강좌 3 - 배열, 튜플, 딕셔너리

https://webnautes.tistory.com/2229 

 

Julia 강좌 4 - 제어문 if ... else, for, break, continue, while, enumerate

https://webnautes.tistory.com/2235 

 

Julia 강좌 5 - 브로드캐스팅(broadcasting)

https://webnautes.tistory.com/2240 

 

Julia 강좌 6 - 변수 유효 범위( Variable Scope ) : 전역(global), 로컬(local)

https://webnautes.tistory.com/2247


Julia 강좌 7 - 모듈(module)

https://webnautes.tistory.com/2253

 

Julia 강좌 8 - 타입(type)

https://webnautes.tistory.com/2260

 

Julia 강좌 9 - 패키지(package)

https://webnautes.tistory.com/2268 

 

 

모듈의 유효 범위에 대한 내용은 아래 포스트 끝부분을 참고하세요. 

 

Julia 강좌 6 - 변수 유효 범위( Variable Scope ) : 전역(global), 로컬(local)

https://webnautes.tistory.com/2247



모듈 사용하기 

Julia의 라이브러리는 모듈 형태로 제공되며, using 문을 사용하여 모듈을 로드할 수 있습니다. 모듈 내에는 변수와 함수들이 포함되며 외부와 분리되어 있는 별도의 환경을 가집니다.  

 

모듈내에서 export로 지정한 함수나 변수는 같은 스코프에 정의된 것처럼 모듈밖에서 이름만으로 접근 및 호출할 수 있지만, export로 지정하지 않은 함수나 변수는 모듈이름.변수이름, 모듈이름.함수이름 처럼 해야 접근 및 호출할 수 있습니다.  다음 예제를 통해 확인하세요. 

 

module ScopeTestModule
# 모듈내 변수 a1과 함수 show_a1을 export로 지정합니다.
export a1
export show_a1

a1 = 25
b1 = 42

function show_a1()
    println(a1)
end

function show_b1()
    println(b1)
end

end
# 모듈 끝에 end를 적어줘야 합니다.



using .ScopeTestModule
# 이제 앞에서 정의한 모듈을 사용합니다.


println(a1)
# 25
# 모듈내에서 export로 지정한 변수는 이름만 사용하여 접근 가능합니다.

println(ScopeTestModule.b1)
# 42
# export로 지정하지 않은 경우엔 모듈이름을 적어줘야 합니다.

show_a1()
# 25
# 모듈내에서 export로 지정한 함수는 이름만 사용하여 호출 가능합니다.

ScopeTestModule.show_b1()
# 42
# export로 지정하지 않은 경우엔 모듈이름을 적어줘야 합니다. 




Julia 언어는 별도의 커맨드라인 도구 없이도 Julia 내부의 패키지 관리자(Pkg)를 사용하여 모듈를 설치, 업데이트, 제거할 수 있습니다.   모듈과 패키지를 같은 의미로 사용합니다. 



다음 코드를 통해 모듈 설치/삭제를 테스트해봅니다. 

 

먼저 SpecialFunctions 모듈을 설치한 후, 설치된 모듈을 확인합니다.

그 다음  SpecialFunctions 모듈을 삭제한 후, 다시 설치된 모듈을 확인합니다. 

 

using Pkg


println("SpecialFunctions 모듈을 설치합니다.")
Pkg.add("SpecialFunctions")
# SpecialFunctions 모듈을 설치합니다.


println("---------------------------------")
println("설치된 모듈을 확인합니다.")

Pkg.status()
# 설치된 모듈을 확인합니다. SpecialFunctions 모듈과 관련 모듈이 설치된 것을 볼 수 있습니다.


println("---------------------------------")

println("SpecialFunctions 모듈을 삭제합니다.")
Pkg.rm("SpecialFunctions")
# SpecialFunctions 모듈을 삭제합니다.


println("---------------------------------")
println("설치된 모듈을 확인합니다.")

Pkg.status()
# 설치된 모듈을 확인합니다. SpecialFunctions 모듈과 관련 모듈이 삭제된 것을 볼 수 있습니다. 



실행결과입니다. 




이제 SpecialFunctions 모듈을 설치한 후,  SpecialFunctions 모듈에 포함된 gamma 함수 및 Bessel 함수를 사용해봅니다. 

 

using Pkg
# 패키지 관리를 위한 Pkg 모듈을 사용합니다.

Pkg.add("SpecialFunctions")
# SpecialFunctions 모듈을 설치합니다. 한번 모듈을 설치한 이후엔 이 코드를 다시 호출할 필요가 없습니다.


using SpecialFunctions
# SpecialFunctions 모듈을 사용합니다.

println(gamma(3))
println(sinint(5))



처음 실행시에는 SpecialFunctions 모듈 설치관련 메시지가 보이고 실행결과가 보입니다. 

 



두번째 실행시에는 설치된 모듈이 없습니다.  SpecialFunctions 모듈이 설치된 후에는 모듈 설치관련 코드는 제거해도 무방합니다.

 




모듈에서 사용할 함수를 지정해줄 수 도 있습니다. 이렇게 하면 모듈에 포함되어 있지만 지정하지 않은 함수는 사용할 수 없습니다.

 

using SpecialFunctions: gamma, sinint
# SpecialFunctions 모듈에서 사용할 함수로 gamma, sinint를 지정합니다.

println(gamma(3))
println(sinint(5))





전역으로 정의된 함수와 모듈에 포함된 함수가 똑같은 이름인 경우 어느 함수를 호출할지 지정해주는 예제 코드입니다.

 

function gamma(x)
    println("I am another 'gamma' function")
    return x^2
end


using SpecialFunctions
# WARNING: using SpecialFunctions.gamma in module Main conflicts with an existing identifier.

# SpecialFunctions 모듈 내에 있는 gamma 함수와 똑같은 이름의 함수가 이미 정의되어있다는 것을 알려줍니다.

println(gamma(3))
# I am another 'gamma' function
# 9

# 전역으로 정의된 함수를 호출합니다.



println(SpecialFunctions.gamma(3))
# 2.0

# 모듈 이름을 지정하여 SpecialFunctions 모듈내에 정의된 함수를 호출합니다.





using 대신에 import를 사용하면 같은 문제가 발생하지 않습니다.  import를 사용하면 모듈 내의 함수 호출시 항상 모듈 이름을 사용해야 하기 때문입니다. 

 

function gamma(x)
    println("I am another 'gamma' function")
    return x^2
end


import SpecialFunctions
# 똑같은 함수가 이미 정의되어 있다는 메시지가 보이지 않습니다.


println(gamma(3))
# I am another 'gamma' function
# 9

println(SpecialFunctions.gamma(3))
# 2.0




모듈을 로드시 import를 사용하면 모듈 내에서 export로 지정했더라도 모듈 외부에서 변수에 접근하거나 함수 호출시 모듈 이름을 적어줘야 합니다.

 

module ScopeTestModule
# 모듈내 변수 a1과 함수 show_a1을 export로 지정합니다.
export a1
export show_a1

a1 = 25
b1 = 42

function show_a1()
    println(a1)
end

function show_b1()
    println(b1)
end

end
# 모듈 끝에 end를 적어줘야 합니다.



import .ScopeTestModule
# 이제 앞에서 정의한 모듈을 사용합니다.


println(ScopeTestModule.a1)
# 25
# 모듈내에서 export로 지정했더라도 모듈 이름만 사용해야 변수에 접근 가능합니다.

ScopeTestModule.show_a1()
# 25
# 모듈내에서 export로 지정했더라도 모듈 이름을 사용해야 험수 호출 가능합니다. 




사용자 정의 모듈

모듈은 변수와 함수를 모아놓은 것으로 모듈 별로 별도의 전역 범위를 가집니다.  export로 지정하면 모듈 외부에서는 변수나 함수 이름만 적어도  접근가능하지만 export로 지정하지 않은 경우에는 변수,함수이름 앞에 모듈 이름을 추가해줘야 합니다.  

 

module MyModule
export func2

a=42

function func1(x)
    return x^2
end

function func2(x)
    return func1(x) + a
end

end

using .MyModule
# MyModule 모듈을 사용합니다.


println(func2(3))
# 51
# export로 지정한 함수는 모듈 외부에서 함수 이름만으로 호출할 수 있습니다.


println(MyModule.func1(3))
# 9
# export로 지정하지 않은 함수를 모듈 외부에서 호출하려면 모듈 이름을 함수 이름앞에 추가해야 합니다.


func1(3)
# export로 지정하지 않은 함수는 모듈 외부에서 함수 이름만으로 호출할 수 없습니다. 에러가 발생합니다.



실행결과입니다. func1(3)을 호출하는 부분에서 에러가 발생했습니다.

 




코드 삽입(Code inclusion)

별도의 파일에 작성된 코드를 포함시키는 예제입니다. include문으로 지정한 파일이 해당 자리에 추가됩니다. 



코드를 테스트하려면 파일을 다음 구조로 저장해야 합니다. 편의상 files 폴더를 없애고 아래 코드에서 include 문에 있는 파일 경로를 수정해도 됩니다. 

 



include 문을 사용하여 별도의 파일에 존재하는 코드를 다른 파일의 코드에 추가하고 있습니다.

 

1.jl, 2.jl 파일에 작성된 함수를 test_module.jl에 작성된 모듈에 추가합니다. test_module.jl 파일에 존재하는 모듈은 다시 hello.jl 파일에 존재하는 코드에 추가됩니다. 



1.jl

모듈이 아니라 func1big 함수를 정의한 코드입니다.

 

function func1big(x)
    return x^2
end



2.jl

모듈이 아니라 변수 a와 func2big 함수를 정의한 코드입니다. 1.jl 파일에 있는 func1big 함수를 호출하고 있습니다.

 

a = 42

function func2big(x)
    return func1big(x) + a
end



test_module.jl

MyBigModule 모듈을 정의하고 있으며 files/1.jl와 files/2.jl에 있는 코드를 추가하고 있습니다. 

 

module MyBigModule

include("files/1.jl")
# files/1.jl에 있는 코드를 이 자리에 추가합니다.
include("files/2.jl")
# files/2.jl에 있는 코드를 이 자리에 추가합니다.

export func2big
# 모듈 외부에서 func2big를 모듈 이름 없이 접근할 수 있도록 합니다.

end 



hello.jl

 

include("test_module.jl")
# test_module.jl에 있는 코드를 이 자리에 추가합니다.

using .MyBigModule
# MyBigModule 모듈을 사용합니다.

print(func2big(3))
# func2big 함수를 호출합니다. 



hello.jl 파일을 실행하면 51이 출력됩니다. 





반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts