diff --git a/site/ko/swift/python_interoperability.ipynb b/site/ko/swift/python_interoperability.ipynb new file mode 100644 index 00000000000..b90aae39a64 --- /dev/null +++ b/site/ko/swift/python_interoperability.ipynb @@ -0,0 +1,548 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "9TV7IYeqifSv" + }, + "source": [ + "##### Copyright 2018 The TensorFlow Authors. [Licensed under the Apache License, Version 2.0](#scrollTo=ByZjmtFgB_Y5)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": {}, + "colab_type": "code", + "id": "tRIJp_4m_Afz" + }, + "outputs": [], + "source": [ + "// #@title Licensed under the Apache License, Version 2.0 (the \"License\"); { display-mode: \"form\" }\n", + "// Licensed under the Apache License, Version 2.0 (the \"License\");\n", + "// you may not use this file except in compliance with the License.\n", + "// You may obtain a copy of the License at\n", + "//\n", + "// https://www.apache.org/licenses/LICENSE-2.0\n", + "//\n", + "// Unless required by applicable law or agreed to in writing, software\n", + "// distributed under the License is distributed on an \"AS IS\" BASIS,\n", + "// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n", + "// See the License for the specific language governing permissions and\n", + "// limitations under the License." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "sI1ZtrdiA4aY" + }, + "source": [ + "\n", + " \n", + " \n", + " \n", + "
\n", + " TensorFlow.org에서 보기\n", + " \n", + " 구글 코랩(Colab)에서 실행하기\n", + " \n", + " 깃허브(GitHub)에서 소스 보기\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "id": "-agGVYp_4GWZ", + "colab_type": "text" + }, + "source": [ + "Note: 이 문서는 텐서플로 커뮤니티에서 번역했습니다. 커뮤니티 번역 활동의 특성상 정확한 번역과 최신 내용을 반영하기 위해 노력함에도 불구하고 [공식 영문 문서](https://github.com/tensorflow/swift/blob/master/docs/site/tutorials/python_interoperability.ipynb)의 내용과 일치하지 않을 수 있습니다. 이 번역에 개선할 부분이 있다면 [tensorflow/docs](https://github.com/tensorflow/docs) 깃허브 저장소로 풀 리퀘스트를 보내주시기 바랍니다. 문서 번역이나 리뷰에 참여하려면 [docs-ko@tensorflow.org](https://groups.google.com/a/tensorflow.org/forum/#!forum/docs-ko)로 메일을 보내주시기 바랍니다." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "8sa42_NblqRE" + }, + "source": [ + "# 파이썬 상호 호환성\n", + "\n", + "텐서플로를 위한 스위프트는 파이썬과 상호 호환됩니다.\n", + "\n", + "스위프트에서 파이썬 모듈을 임포트해서, 스위프트와 파이썬 사이의 값을 바꾸거나 파이썬 함수를 호출할 수 있습니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + }, + "colab_type": "code", + "id": "kZRlD4utdPuX", + "outputId": "101c8d8f-9d75-485f-9678-d27ece433fbb" + }, + "outputs": [], + "source": [ + "import Python\n", + "print(Python.version)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 파이썬 버전 설정" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "기본적으로 `import Python`를 하면, 스위프트는 시스템 라이브러리 경로에 따라 설치된 최신 버전의 파이썬을 검색합니다. \n", + "특정한 파이썬을 설치하려면, `PYTHON_LIBRARY` 환경변수에 설치시 제공받은 `libpython` 공유 라이브러리를 설정합니다. 예를 들어: \n", + "\n", + "`export PYTHON_LIBRARY=\"~/anaconda3/lib/libpython3.7m.so\"`\n", + "\n", + "정확한 파일명은 파이썬 환경과 플랫폼마다 다를 수 있습니다." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "또는 스위프트가 시스템 라이브러리 경로에서 알맞은 파이썬 버전을 찾도록 해서 `PYTHON_VERSION` 환경변수를 설정할 수 있습니다. `PYTHON_LIBRARY`가 `PYTHON_VERSION` 보다 우선한다는 점을 유의해야 합니다.\n", + "\n", + "또한 코드에서 `PYTHON_VERSION` 설정과 동일한 기능을 하는 `PythonLibrary.useVersion` 함수를 호출할 수 있습니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "// PythonLibrary.useVersion(2)\n", + "// PythonLibrary.useVersion(3, 7)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "__Note: 파이썬을 임포트한 직후, 파이썬 코드를 호출하기 전에 `PythonLibrary.useVersion`을 실행해야 합니다. 이것은 파이썬 버전을 동적으로 바꾸는 데 사용될 수 없습니다.__" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[파이썬 라이브러리 로딩 과정에서 생성되는 디버그 출력](https://github.com/apple/swift/pull/20674#discussion_r235207008)을 확인하기 위해서 `PYTHON_LOADER_LOGGING=1`를 설정하세요. " + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "rU0WY_sJodio" + }, + "source": [ + "## 기초\n", + "\n", + "스위프트에서 `PythonObject`는 파이썬 객체를 나타냅니다.\n", + "모든 파이썬 API는 `PythonObject` 인스턴스를 사용하거나 반환합니다.\n", + "\n", + "스위프트에서 기본형(숫자 및 배열처럼)은 `PythonObject`로 전환할 수 있습니다. 몇몇 경우에 (`PythonConvertible` 인수를 받는 리터럴과 함수의 경우), 변환이 암묵적으로 일어납니다. 스위프트 값을 `PythonObject`에 명시적으로 지정하려면 `PythonObject` 이니셜라이저를 사용합니다.\n", + "\n", + "`PythonObject`는 숫자 연산, 인덱싱, 반복을 포함한 많은 표준 연산을 정의합니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + }, + "colab_type": "code", + "id": "kqXILiXhq-iM", + "outputId": "074fbc43-9c87-4fb2-b970-ffeaff12987a" + }, + "outputs": [], + "source": [ + "// 표준 스위프트 자료형을 Python으로 변환합니다.\n", + "let pythonInt: PythonObject = 1\n", + "let pythonFloat: PythonObject = 3.0\n", + "let pythonString: PythonObject = \"Hello Python!\"\n", + "let pythonRange: PythonObject = PythonObject(5..<10)\n", + "let pythonArray: PythonObject = [1, 2, 3, 4]\n", + "let pythonDict: PythonObject = [\"foo\": [0], \"bar\": [1, 2, 3]]\n", + "\n", + "// 파이썬 객체에 표준 연산을 수행합니다.\n", + "print(pythonInt + pythonFloat)\n", + "print(pythonString[0..<6])\n", + "print(pythonRange)\n", + "print(pythonArray[2])\n", + "print(pythonDict[\"bar\"])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 102 + }, + "colab_type": "code", + "id": "fEAEyUExXT3I", + "outputId": "6e53881b-8520-4d3a-efda-9ac3e4f5a53a" + }, + "outputs": [], + "source": [ + "// 파이썬 객체를 다시 스위프트로 변환합니다.\n", + "let int = Int(pythonInt)!\n", + "let float = Float(pythonFloat)!\n", + "let string = String(pythonString)!\n", + "let range = Range(pythonRange)!\n", + "let array: [Int] = Array(pythonArray)!\n", + "let dict: [String: [Int]] = Dictionary(pythonDict)!\n", + "\n", + "// 표준 연산을 수행합니다.\n", + "// 출력은 파이썬과 동일합니다!\n", + "print(Float(int) + float)\n", + "print(string.prefix(6))\n", + "print(range)\n", + "print(array[2])\n", + "print(dict[\"bar\"]!)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "1pMewsl0VgnJ" + }, + "source": [ + "`PythonObject`는 많은 표준 스위프트 프로토콜에 대해 적합하도록 정의합니다:\n", + "* `Equatable`\n", + "* `Comparable`\n", + "* `Hashable`\n", + "* `SignedNumeric`\n", + "* `Strideable`\n", + "* `MutableCollection`\n", + "* 모든 `ExpressibleBy_Literal` 프로토콜\n", + "\n", + "이러한 적합성은 형안전(type-safe)하지 않다는 점에 유의해야 합니다: 호환되지 않는 `PythonObject` 인스턴스에서 프로토콜 기능을 사용하려고 할 때 충돌이 발생할 수 있습니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 119 + }, + "colab_type": "code", + "id": "W9bUsiOxVf_v", + "outputId": "abd837e0-de01-415d-d09e-a414aff54af7" + }, + "outputs": [], + "source": [ + "let one: PythonObject = 1\n", + "print(one == one)\n", + "print(one < one)\n", + "print(one + one)\n", + "\n", + "let array: PythonObject = [1, 2, 3]\n", + "for (i, x) in array.enumerated() {\n", + " print(i, x)\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "w3lmTRCWT5sS" + }, + "source": [ + "튜플을 파이썬에서 스위프트로 변환하려면, 정확한 튜플의 길이를 알아야 합니다.\n", + "\n", + "다음 인스턴스 메서드 중 하나를 호출합니다:\n", + "- `PythonObject.tuple2`\n", + "- `PythonObject.tuple3`\n", + "- `PythonObject.tuple4`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 51 + }, + "colab_type": "code", + "id": "fQ0HEX89T4mW", + "outputId": "e8333b10-0d79-443d-fa2c-7322ce199be4" + }, + "outputs": [], + "source": [ + "let pythonTuple = Python.tuple([1, 2, 3])\n", + "print(pythonTuple, Python.len(pythonTuple))\n", + "\n", + "// 스위프트로 변환합니다.\n", + "let tuple = pythonTuple.tuple3\n", + "print(tuple)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Te7sNNx9c_am" + }, + "source": [ + "## 파이썬 내장 객체\n", + "\n", + "전역 `Python` 인터페이스를 활용해 파이썬 내장 객체에 접근합니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + }, + "colab_type": "code", + "id": "jpcOByipc75O", + "outputId": "483be552-f2df-498c-e3c6-b0946040108d" + }, + "outputs": [], + "source": [ + "// `Python.builtins`은 모든 파이썬 내장 객체의 딕셔너리입니다.\n", + "_ = Python.builtins\n", + "\n", + "// 파이썬 내장 객체를 사용합니다.\n", + "print(Python.type(1))\n", + "print(Python.len([1, 2, 3]))\n", + "print(Python.sum([1, 2, 3]))" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "H2wwUL1tY3JX" + }, + "source": [ + "## 파이썬 모듈 임포트\n", + "\n", + "`Python.import`를 사용하여 파이썬 모듈을 임포트합니다. 이것은 `Python`의 `import` 키워드처럼 동작합니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + }, + "colab_type": "code", + "id": "XrZee8n3Y17_", + "outputId": "dc97f143-8af5-42bf-f5cd-2f4c54cc9bb1" + }, + "outputs": [], + "source": [ + "let np = Python.import(\"numpy\")\n", + "print(np)\n", + "let zeros = np.ones([2, 3])\n", + "print(zeros)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "hQvza3dUXlr0" + }, + "source": [ + "안전하게 패키지를 가져오기 위해 예외처리 함수 `Python.attemptImport`를 사용하세요." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 34 + }, + "colab_type": "code", + "id": "QD-uQGuaXhrM", + "outputId": "6dec8823-f4f2-4dcb-da7f-4ee07558f1ef" + }, + "outputs": [], + "source": [ + "let maybeModule = try? Python.attemptImport(\"nonexistent_module\")\n", + "print(maybeModule)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "Qej_Z6V3mZnG" + }, + "source": [ + "## `numpy.ndarray`로 변환\n", + "\n", + "다음 스위프트 자료형은 `numpy.ndarray`로 변환할 수 있습니다:\n", + "- `Array`\n", + "- `ShapedArray`\n", + "- `Tensor`\n", + "\n", + "`Numpy.ndarray`의 `dtype`이 `Element` 또는 `Scalar`의 일반 파라미터 타입과 호환되어야만 변환이 성공합니다.\n", + "\n", + "`Array`의 경우 `numpy.ndarray`가 1-D일 경우에만 `numpy`에서 변환이 성공합니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + }, + "colab_type": "code", + "id": "hPvKgZBeDQ1p", + "outputId": "07991f82-bb7e-4e9d-d0c0-481018a3ff5a" + }, + "outputs": [], + "source": [ + "import TensorFlow\n", + "\n", + "let numpyArray = np.ones([4], dtype: np.float32)\n", + "print(\"Swift type:\", type(of: numpyArray))\n", + "print(\"Python type:\", Python.type(numpyArray))\n", + "print(numpyArray.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 68 + }, + "colab_type": "code", + "id": "ZuDgZ5cBS3Uk", + "outputId": "83c98b1c-839f-4fd2-a4a8-36d6c068d25f" + }, + "outputs": [], + "source": [ + "// `numpy.ndarray`에서 스위프트 타입으로 변환하는 예제.\n", + "let array: [Float] = Array(numpy: numpyArray)!\n", + "let shapedArray = ShapedArray(numpy: numpyArray)!\n", + "let tensor = Tensor(numpy: numpyArray)!\n", + "\n", + "// 스위프트 타입에서 `numpy.ndarray`으로 변환하는 예제.\n", + "print(array.makeNumpyArray())\n", + "print(shapedArray.makeNumpyArray())\n", + "print(tensor.makeNumpyArray())\n", + "\n", + "// dtype이 다른 예제.\n", + "let doubleArray: [Double] = Array(numpy: np.ones([3], dtype: np.float))!\n", + "let intTensor = Tensor(numpy: np.ones([2, 3], dtype: np.int32))!" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text", + "id": "8EQFZZ5iafwh" + }, + "source": [ + "## 이미지 표시\n", + "\n", + "파이썬 노트북에서처럼 `matplotlib`를 이용해 이미지를 결과 창에 표시할 수 있습니다." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 658 + }, + "colab_type": "code", + "id": "jUzsa2cxafQV", + "outputId": "34f4d6e6-4e3c-4666-d2c2-34508aa01264" + }, + "outputs": [], + "source": [ + "// 준비.\n", + "%include \"EnableIPythonDisplay.swift\"\n", + "IPythonDisplay.shell.enable_matplotlib(\"inline\")\n", + "\n", + "let np = Python.import(\"numpy\")\n", + "let plt = Python.import(\"matplotlib.pyplot\")\n", + "\n", + "let time = np.arange(0, 10, 0.01)\n", + "let amplitude = np.exp(-0.1 * time)\n", + "let position = amplitude * np.sin(3 * time)\n", + "\n", + "plt.figure(figsize: [15, 10])\n", + "\n", + "plt.plot(time, position)\n", + "plt.plot(time, amplitude)\n", + "plt.plot(time, -amplitude)\n", + "\n", + "plt.xlabel(\"Time (s)\")\n", + "plt.ylabel(\"Position (m)\")\n", + "plt.title(\"Oscillations\")\n", + "\n", + "plt.show()" + ] + } + ], + "metadata": { + "colab": { + "collapsed_sections": [], + "name": "Python interoperability.ipynb", + "provenance": [], + "toc_visible": true, + "version": "0.3.2" + }, + "kernelspec": { + "display_name": "Swift", + "language": "swift", + "name": "swift" + }, + "language_info": { + "file_extension": ".swift", + "mimetype": "text/x-swift", + "name": "swift", + "version": "" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +}