إمكانية التشغيل البيني بيثون

عرض على TensorFlow.org تشغيل في جوجل كولاب عرض المصدر على جيثب

يدعم Swift For TensorFlow إمكانية التشغيل التفاعلي لـ Python.

يمكنك استيراد وحدات Python من Swift، واستدعاء وظائف Python، وتحويل القيم بين Swift وPython.

import PythonKit
print(Python.version)
3.6.9 (default, Oct  8 2020, 12:12:24) 
[GCC 8.4.0]

تحديد إصدار بايثون

افتراضيًا، عند import Python ، يبحث Swift في مسارات مكتبة النظام عن أحدث إصدار مثبت من Python. لاستخدام تثبيت Python محدد، قم بتعيين متغير البيئة PYTHON_LIBRARY على مكتبة libpython المشتركة التي يوفرها التثبيت. على سبيل المثال:

export PYTHON_LIBRARY="~/anaconda3/lib/libpython3.7m.so"

سيختلف اسم الملف الدقيق عبر بيئات ومنصات Python.

وبدلاً من ذلك، يمكنك تعيين متغير البيئة PYTHON_VERSION ، الذي يوجه Swift للبحث في مسارات مكتبة النظام للحصول على إصدار Python المطابق. لاحظ أن PYTHON_LIBRARY لها الأسبقية على PYTHON_VERSION .

في التعليمات البرمجية، يمكنك أيضًا استدعاء وظيفة PythonLibrary.useVersion ، والتي تعادل إعداد PYTHON_VERSION .

// PythonLibrary.useVersion(2)
// PythonLibrary.useVersion(3, 7)

ملاحظة: يجب عليك تشغيل PythonLibrary.useVersion مباشرة بعد import Python ، قبل استدعاء أي رمز Python. لا يمكن استخدامه للتبديل ديناميكيًا بين إصدارات Python.

قم بتعيين PYTHON_LOADER_LOGGING=1 لرؤية مخرجات التصحيح لتحميل مكتبة Python .

الأساسيات

في Swift، يمثل PythonObject كائنًا من Python. تستخدم جميع واجهات برمجة تطبيقات Python وتعيد مثيلات PythonObject .

الأنواع الأساسية في Swift (مثل الأرقام والمصفوفات) قابلة للتحويل إلى PythonObject . في بعض الحالات (بالنسبة للأحرف والوظائف التي تستخدم وسيطات PythonConvertible )، يحدث التحويل ضمنيًا. لإرسال قيمة Swift بشكل صريح إلى 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 التوافق مع العديد من بروتوكولات Swift القياسية:

  • 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

لتحويل الصف من Python إلى Swift، يجب عليك معرفة مدى دقة الصف بشكل ثابت.

اتصل بأحد أساليب المثيل التالية:

  • 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 العالمية.

// `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 لاستيراد وحدة Python. إنه يعمل مثل الكلمة الرئيسية 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

يمكن تحويل أنواع Swift التالية من وإلى numpy.ndarray :

  • Array<Element>
  • ShapedArray<Scalar>
  • Tensor<Scalar>

ينجح التحويل فقط إذا كان dtype الخاص بـ numpy.ndarray متوافقًا مع نوع المعلمة العامة Element أو Scalar .

بالنسبة إلى Array ، ينجح التحويل من numpy فقط إذا كان numpy.ndarray أحادي الأبعاد.

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 ، تمامًا كما هو الحال في دفاتر ملاحظات Python.

// 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.