Swift For TensorFlow از قابلیت همکاری پایتون پشتیبانی می کند.
می توانید ماژول های پایتون را از سویفت وارد کنید، توابع پایتون را فراخوانی کنید و مقادیر را بین سویفت و پایتون تبدیل کنید.
import PythonKit
print(Python.version)
3.6.9 (default, Oct 8 2020, 12:12:24) [GCC 8.4.0]
تنظیم نسخه پایتون
بهطور پیشفرض، وقتی import Python
، سوئیفت مسیرهای کتابخانه سیستم را برای جدیدترین نسخه نصبشده پایتون جستجو میکند. برای استفاده از یک نصب خاص پایتون، متغیر محیطی PYTHON_LIBRARY
را روی کتابخانه اشتراکی libpython
که توسط نصب ارائه شده است، تنظیم کنید. به عنوان مثال:
export PYTHON_LIBRARY="~/anaconda3/lib/libpython3.7m.so"
نام دقیق فایل در محیطها و پلتفرمهای پایتون متفاوت خواهد بود.
همچنین، میتوانید متغیر محیطی PYTHON_VERSION
را تنظیم کنید، که به Swift دستور میدهد مسیرهای کتابخانه سیستم را برای نسخه پایتون منطبق جستجو کند. توجه داشته باشید که PYTHON_LIBRARY
بر PYTHON_VERSION
ارجحیت دارد.
در کد، میتوانید تابع PythonLibrary.useVersion
را نیز فراخوانی کنید، که معادل تنظیم PYTHON_VERSION
است.
// PythonLibrary.useVersion(2)
// PythonLibrary.useVersion(3, 7)
توجه: باید PythonLibrary.useVersion
درست پس از import Python
، قبل از فراخوانی هر کد پایتون اجرا کنید. نمی توان از آن برای تعویض پویا نسخه های پایتون استفاده کرد.
PYTHON_LOADER_LOGGING=1
را برای مشاهده خروجی اشکال زدایی برای بارگیری کتابخانه پایتون تنظیم کنید.
مبانی
در سوئیفت، PythonObject
یک شی از پایتون را نشان می دهد. همه APIهای پایتون از نمونههای PythonObject
استفاده میکنند و برمیگردانند.
انواع پایه در سوئیفت (مانند اعداد و آرایه ها) به PythonObject
قابل تبدیل هستند. در برخی موارد (برای کلمات و توابعی که از آرگومانهای PythonConvertible
استفاده میکنند)، تبدیل به طور ضمنی اتفاق میافتد. برای ارسال صریح مقدار سوئیفت به PythonObject
، از مقداردهی اولیه PythonObject
استفاده کنید.
PythonObject
بسیاری از عملیات استاندارد از جمله عملیات عددی، نمایه سازی و تکرار را تعریف می کند.
// Convert standard Swift types to Python.
let pythonInt: PythonObject = 1
let pythonFloat: PythonObject = 3.0
let pythonString: PythonObject = "Hello Python!"
let pythonRange: PythonObject = PythonObject(5..<10)
let pythonArray: PythonObject = [1, 2, 3, 4]
let pythonDict: PythonObject = ["foo": [0], "bar": [1, 2, 3]]
// Perform standard operations on Python objects.
print(pythonInt + pythonFloat)
print(pythonString[0..<6])
print(pythonRange)
print(pythonArray[2])
print(pythonDict["bar"])
4.0 Hello slice(5, 10, None) 3 [1, 2, 3]
// Convert Python objects back to Swift.
let int = Int(pythonInt)!
let float = Float(pythonFloat)!
let string = String(pythonString)!
let range = Range<Int>(pythonRange)!
let array: [Int] = Array(pythonArray)!
let dict: [String: [Int]] = Dictionary(pythonDict)!
// Perform standard operations.
// Outputs are the same as Python!
print(Float(int) + float)
print(string.prefix(6))
print(range)
print(array[2])
print(dict["bar"]!)
4.0 Hello 5..<10 3 [1, 2, 3]
PythonObject
انطباق ها را با بسیاری از پروتکل های استاندارد سوئیفت تعریف می کند:
-
Equatable
-
Comparable
-
Hashable
-
SignedNumeric
-
Strideable
-
MutableCollection
- همه پروتکل های
ExpressibleBy_Literal
توجه داشته باشید که این انطباق ها از نظر نوع ایمن نیستند: اگر بخواهید از عملکرد پروتکل از یک نمونه PythonObject
ناسازگار استفاده کنید، خرابی ها رخ می دهد.
let one: PythonObject = 1
print(one == one)
print(one < one)
print(one + one)
let array: PythonObject = [1, 2, 3]
for (i, x) in array.enumerated() {
print(i, x)
}
True False 2 0 1 1 2 2 3
برای تبدیل تاپل ها از پایتون به سوئیفت، باید به صورت ایستا آریتی تاپل را بدانید.
یکی از روش های نمونه زیر را فراخوانی کنید:
-
PythonObject.tuple2
-
PythonObject.tuple3
-
PythonObject.tuple4
let pythonTuple = Python.tuple([1, 2, 3])
print(pythonTuple, Python.len(pythonTuple))
// Convert to Swift.
let tuple = pythonTuple.tuple3
print(tuple)
(1, 2, 3) 3 (1, 2, 3)
بیلدین های پایتون
از طریق رابط جهانی Python
به سازههای پایتون دسترسی پیدا کنید.
// `Python.builtins` is a dictionary of all Python builtins.
_ = Python.builtins
// Try some Python builtins.
print(Python.type(1))
print(Python.len([1, 2, 3]))
print(Python.sum([1, 2, 3]))
<class 'int'> 3 6
وارد کردن ماژول های پایتون
برای وارد کردن ماژول پایتون Python.import
استفاده کنید. مانند کلمه کلیدی import
در Python
کار می کند.
let np = Python.import("numpy")
print(np)
let zeros = np.ones([2, 3])
print(zeros)
<module 'numpy' from '/tmpfs/src/tf_docs_env/lib/python3.6/site-packages/numpy/__init__.py'> [[1. 1. 1.] [1. 1. 1.]]
از تابع پرتاب Python.attemptImport
برای انجام وارد کردن ایمن استفاده کنید.
let maybeModule = try? Python.attemptImport("nonexistent_module")
print(maybeModule)
nil
تبدیل با numpy.ndarray
انواع سوئیفت زیر را می توان به numpy.ndarray
و از آن تبدیل کرد:
-
Array<Element>
-
ShapedArray<Scalar>
-
Tensor<Scalar>
تبدیل فقط در صورتی موفق می شود که dtype
numpy.ndarray
با نوع پارامتر عمومی Element
یا Scalar
سازگار باشد.
برای Array
، تبدیل از numpy
فقط در صورتی موفق می شود که numpy.ndarray
1-D باشد.
import TensorFlow
let numpyArray = np.ones([4], dtype: np.float32)
print("Swift type:", type(of: numpyArray))
print("Python type:", Python.type(numpyArray))
print(numpyArray.shape)
Swift type: PythonObject Python type: <class 'numpy.ndarray'> (4,)
// Examples of converting `numpy.ndarray` to Swift types.
let array: [Float] = Array(numpy: numpyArray)!
let shapedArray = ShapedArray<Float>(numpy: numpyArray)!
let tensor = Tensor<Float>(numpy: numpyArray)!
// Examples of converting Swift types to `numpy.ndarray`.
print(array.makeNumpyArray())
print(shapedArray.makeNumpyArray())
print(tensor.makeNumpyArray())
// Examples with different dtypes.
let doubleArray: [Double] = Array(numpy: np.ones([3], dtype: np.float))!
let intTensor = Tensor<Int32>(numpy: np.ones([2, 3], dtype: np.int32))!
[1. 1. 1. 1.] [1. 1. 1. 1.] [1. 1. 1. 1.]
نمایش تصاویر
شما می توانید تصاویر را به صورت خطی با استفاده از matplotlib
نمایش دهید، درست مانند نوت بوک های پایتون.
// This cell is here to display plots inside a Jupyter Notebook.
// Do not copy it into another environment.
%include "EnableIPythonDisplay.swift"
print(IPythonDisplay.shell.enable_matplotlib("inline"))
('inline', 'module://ipykernel.pylab.backend_inline')
let np = Python.import("numpy")
let plt = Python.import("matplotlib.pyplot")
let time = np.arange(0, 10, 0.01)
let amplitude = np.exp(-0.1 * time)
let position = amplitude * np.sin(3 * time)
plt.figure(figsize: [15, 10])
plt.plot(time, position)
plt.plot(time, amplitude)
plt.plot(time, -amplitude)
plt.xlabel("Time (s)")
plt.ylabel("Position (m)")
plt.title("Oscillations")
plt.show()
Use `print()` to show values.