الفرق بين المراجعتين لصفحة: «Python/copy»
أنشأ الصفحة ب'<noinclude>{{DISPLAYTITLE:الوحدة <code>copy</code> في بايثون}}</noinclude> لا تنشئ عبارات الإسناد في بايثون نسخة من ال...' |
لا ملخص تعديل |
||
سطر 5: | سطر 5: | ||
تقدّم هذه الوحدة مجموعة من عمليات النسخ السطحية والعميقة. | تقدّم هذه الوحدة مجموعة من عمليات النسخ السطحية والعميقة. | ||
copy.copy(x) | === <code>copy.copy(x)</code> === | ||
تعيد الدالة نسخة سطحية من الكائن المعطى. | تعيد الدالة نسخة سطحية من الكائن المعطى. | ||
copy.deepcopy(x) | === <code>copy.deepcopy(x)</code> === | ||
تعيد الدالة نسخة عميقة من الكائن المعطى. | تعيد الدالة نسخة عميقة من الكائن المعطى. | ||
exception copy.error | === <code>exception copy.error</code> === | ||
يُطلق هذا الاستثناء عند حدوث أخطاء خاصة بهذه الوحدة. | يُطلق هذا الاستثناء عند حدوث أخطاء خاصة بهذه الوحدة. | ||
يظهر الفرق بين عمليتي النسخ العميقة والسطحية في الكائنات المركّبة compound objects (الكائنات التي تتضمّن كائنات أخرى، مثل القوائم أو نسخ الأصناف): | يظهر الفرق بين عمليتي النسخ العميقة والسطحية في الكائنات المركّبة compound objects (الكائنات التي تتضمّن كائنات أخرى، مثل القوائم أو نسخ الأصناف): | ||
تنشئ عملية النسخ السطحية كائنًا مركّبًا جديدًا ثم تدرج فيه (قدر الإمكان) إشارات references إلى الكائنات الموجودة في الكائن الأصلي. | * تنشئ عملية النسخ السطحية كائنًا مركّبًا جديدًا ثم تدرج فيه (قدر الإمكان) إشارات references إلى الكائنات الموجودة في الكائن الأصلي. | ||
أما عملية النسخ العميقة فتنشئ كائنًا مركبًّا جديدًا ثم تدرج تعاوديًا recursively نسخًا من الكائنات الموجودة في الكائن الأصلي. | * أما عملية النسخ العميقة فتنشئ كائنًا مركبًّا جديدًا ثم تدرج تعاوديًا recursively نسخًا من الكائنات الموجودة في الكائن الأصلي. | ||
عادة ما تعاني عمليات النسخ العميق من مشكلتين لا تظهران في عمليات النسخ السطحي: | عادة ما تعاني عمليات النسخ العميق من مشكلتين لا تظهران في عمليات النسخ السطحي: | ||
* قد تتسب الكائنات التعاودية (وهي كائنات مركّبة تتضمن على نحو مباشر أو غير مباشر إشارات إلى نفسها) في حدوث حلقة تعاودية. | |||
تتجاوز دالة deepcopy() هذه المشاكل عن طريق: | * تنسخ عمليات النسخ العميق كلّ شيء، وقد يتسبب هذا في نسخ ما هو فائض عن الحاجة، مثل البيانات التي يفترض بها أن تكون مشتركة بين النسخ. | ||
تتجاوز دالة <code>deepcopy()</code> هذه المشاكل عن طريق: | |||
* الاحتفاظ بقاموس "memo" يتضمن الكائنات التي يجري نسخها في عملية النسخ الحالية. | * الاحتفاظ [[Python/dict|بقاموس]] "memo" يتضمن الكائنات التي يجري نسخها في عملية النسخ الحالية. | ||
* السماح بالأصناف المعرّفة من قبل المستخدم بإعادة تعريف override عملية النسخ الخاصة بمجموعة المكونات المنسوخة. | * السماح بالأصناف المعرّفة من قبل المستخدم بإعادة تعريف override عملية النسخ الخاصة بمجموعة المكونات المنسوخة. | ||
لا تنسخ هذه الوحدة أنواعًا مثل | لا تنسخ هذه الوحدة أنواعًا مثل [[Python/modules|module]]، method، stack frame، file، socket، window، [[Python/array|array]] أو أي أنواع أخرى مشابهة. تنسخ الوحدة الدوال والأصناف (سطحيًا وبعمق) وذلك بإعادة الكائن الأصلي دون أي تعديل، وهذه الطريقة متوافقة مع طريقة تعامل وحدة [[Python/pickle|pickle]] مع الدوال والأصناف. | ||
يمكن إنشاء نسخ سطحية من القواميس بواسطة التابع <code>[[Python/dict/copy|dict.copy()]]</code>، وإنشاء نسخ سطحية من [[Python/list|القوائم]] عن طريق [[Python/list#.D9.81.D9.87.D8.B1.D8.B3.D8.A9 .D8.A7.D9.84.D9.82.D9.88.D8.A7.D8.A6.D9.85 .D9.88.D8.A7.D9.82.D8.AA.D8.B7.D8.A7.D8.B9 .D8.A3.D8.AC.D8.B2.D8.A7.D8.A1 .D9.85.D9.86.D9.87.D8.A7|اقتطاع القائمة]] بأكملها وإسنادها إلى متغيّر، فعلى سبيل المثال: <code>copied_list = original_list[:]</code>. | |||
يمكن | يمكن [[Python/class|للأصناف]] استخدام نفس الواجهات المستخدمة في التحكم في عملية pickling للتحكم بعملية النسخ. راجع وحدة [[Python/pickle|pickle]] للاطلاع على هذه التوابع. وفي الواقع تستخدم وحدة <code>copy</code> دوال pickle المسجّلة من وحدة [[Python/copyreg|copyreg]]. | ||
ليعرّف الصنف طريقته الخاصة في إجراء عملية النسخ، يمكن تعريف التابعين الخاصين __copy__() و __deepcopy__(). يستدعى التابع الأول لإضافة عمليات النسخ السطحية، ولا يحتاج هذا التابع إلى تمرير أيّ معاملات. أما التابع الثاني فيستدعى لإضافة عمليات النسخ العميق، ويحتاج إلى تمرير معامل واحد هو قاموس memo. إن كان التابع | ليعرّف الصنف طريقته الخاصة في إجراء عملية النسخ، يمكن تعريف التابعين الخاصين <code>__copy__()</code> و <code>__deepcopy__()</code>. يستدعى التابع الأول لإضافة عمليات النسخ السطحية، ولا يحتاج هذا التابع إلى تمرير أيّ معاملات. أما التابع الثاني فيستدعى لإضافة عمليات النسخ العميق، ويحتاج إلى تمرير معامل واحد هو قاموس memo. إن كان التابع <code>__deepcopy__()</code> بحاجة إلى إنشاء نسخة عميقة من مكوّن ما، فيجب عليه استدعاء الدالة <code>deepcopy()</code> مع تمرير المكوّن كمعامل أوّل، وقاموس memo كمعامل ثانٍ. | ||
== انظر أيضًا == | == انظر أيضًا == | ||
* وحدة pickle في بايثون. | * [[Python/pickle|وحدة pickle في بايثون.]] | ||
== مصادر == | == مصادر == |
مراجعة 10:58، 22 أغسطس 2018
لا تنشئ عبارات الإسناد في بايثون نسخة من الكائنات، بل تربط بين الهدف والكائن. ولكن تظهر الحاجة إلى إنشاء نسخ من الكائنات في المجموعات التي تكون قابلة للتعديل أو التي تتضمّن عناصر قابلة للتعديل، بحيث يكون بالإمكان تغيير نسخة دون انتقال تلك التغييرات إلى الكائن الآخر.
تقدّم هذه الوحدة مجموعة من عمليات النسخ السطحية والعميقة.
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 في توثيق بايثون الرسمي.