الوحدة copy في بايثون

من موسوعة حسوب


لا تنشئ عبارات الإسناد في بايثون نسخة من الكائنات، بل تربط بين الهدف والكائن. ولكن تظهر الحاجة إلى إنشاء نسخ من الكائنات في المجموعات التي تكون قابلة للتعديل أو التي تتضمّن عناصر قابلة للتعديل، بحيث يكون بالإمكان تغيير نسخة دون انتقال تلك التغييرات إلى الكائن الآخر.

دوال الوحدة copy

تقدّم هذه الوحدة مجموعة من عمليات النسخ السطحية والعميقة.

copy.copy(x)‎

تعيد الدالة نسخة سطحية من الكائن المعطى.

copy.deepcopy(x)‎

تعيد الدالة نسخة عميقة من الكائن المعطى.

exception copy.error

يُطلق هذا الاستثناء عند حدوث أخطاء خاصة بهذه الوحدة.

يظهر الفرق بين عمليتي النسخ العميقة والسطحية في الكائنات المركّبة compound objects (الكائنات التي تتضمّن كائنات أخرى، مثل القوائم أو نسخ الأصناف):

  • تنشئ عملية النسخ السطحية كائنًا مركّبًا جديدًا ثم تدرج فيه (قدر الإمكان) إشارات references إلى الكائنات الموجودة في الكائن الأصلي.
  • أما عملية النسخ العميقة فتنشئ كائنًا مركبًّا جديدًا ثم تدرج تعاوديًا recursively نسخًا من الكائنات الموجودة في الكائن الأصلي.

عادة ما تعاني عمليات النسخ العميق من مشكلتين لا تظهران في عمليات النسخ السطحي:

  • قد تتسب الكائنات التعاودية (وهي كائنات مركّبة تتضمن على نحو مباشر أو غير مباشر إشارات إلى نفسها) في حدوث حلقة تعاودية.
  • تنسخ عمليات النسخ العميق كلّ شيء، وقد يتسبب هذا في نسخ ما هو فائض عن الحاجة، مثل البيانات التي يفترض بها أن تكون مشتركة بين النسخ.

تتجاوز دالة deepcopy()‎ هذه المشاكل عن طريق:

  • الاحتفاظ بقاموس "memo" يتضمن الكائنات التي يجري نسخها في عملية النسخ الحالية.
  • السماح بالأصناف المعرّفة من قبل المستخدم بإعادة تعريف override عملية النسخ الخاصة بمجموعة المكونات المنسوخة.

لا تنسخ هذه الوحدة أنواعًا مثل module، method، stack frame، file، socket، window، array أو أي أنواع أخرى مشابهة. تنسخ الوحدة الدوال والأصناف (سطحيًا وبعمق) وذلك بإعادة الكائن الأصلي دون أي تعديل، وهذه الطريقة متوافقة مع طريقة تعامل وحدة pickle مع الدوال والأصناف.

يمكن إنشاء نسخ سطحية من القواميس بواسطة التابع dict.copy()‎، وإنشاء نسخ سطحية من القوائم عن طريق اقتطاع القائمة بأكملها وإسنادها إلى متغيّر، فعلى سبيل المثال: copied_list = original_list[:]‎.

يمكن للأصناف استخدام نفس الواجهات المستخدمة في التحكم في عملية pickling للتحكم بعملية النسخ. راجع وحدة pickle للاطلاع على هذه التوابع. وفي الواقع تستخدم وحدة copy دوال pickle المسجّلة من وحدة copyreg.

ليعرّف الصنف طريقته الخاصة في إجراء عملية النسخ، يمكن تعريف التابعين الخاصين ‎__copy__()‎ و ‎__deepcopy__()‎. يستدعى التابع الأول لإضافة عمليات النسخ السطحية، ولا يحتاج هذا التابع إلى تمرير أيّ معاملات. أما التابع الثاني فيستدعى لإضافة عمليات النسخ العميق، ويحتاج إلى تمرير معامل واحد هو قاموس memo. إن كان التابع ‎__deepcopy__‎()‎ بحاجة إلى إنشاء نسخة عميقة من مكوّن ما، فيجب عليه استدعاء الدالة deepcopy()‎ مع تمرير المكوّن كمعامل أوّل، وقاموس memo كمعامل ثانٍ.

انظر أيضًا

مصادر

صفحة Shallow and deep copy operations في توثيق بايثون الرسمي.