<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Reyhane, Author at فيلم تعلم البرمجيات للطالب العربي</title>
	<atom:link href="https://arabdars.com/author/usefi/feed/" rel="self" type="application/rss+xml" />
	<link>https://arabdars.com/author/usefi/</link>
	<description>Arab Dars</description>
	<lastBuildDate>Mon, 21 Sep 2020 16:52:03 +0000</lastBuildDate>
	<language>ar</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.1</generator>

<image>
	<url>https://arabdars.com/wp-content/uploads/cropped-fig2_low-32x32.png</url>
	<title>Reyhane, Author at فيلم تعلم البرمجيات للطالب العربي</title>
	<link>https://arabdars.com/author/usefi/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>ميتاكلاس بايثون</title>
		<link>https://arabdars.com/%d9%85%d9%8a%d8%aa%d8%a7%d9%83%d9%84%d8%a7%d8%b3-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/</link>
					<comments>https://arabdars.com/%d9%85%d9%8a%d8%aa%d8%a7%d9%83%d9%84%d8%a7%d8%b3-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/#respond</comments>
		
		<dc:creator><![CDATA[Reyhane]]></dc:creator>
		<pubDate>Mon, 21 Sep 2020 16:52:03 +0000</pubDate>
				<category><![CDATA[الماتلاب Matlab]]></category>
		<guid isPermaLink="false">https://arabdars.com/?p=1631</guid>

					<description><![CDATA[<p>جدول المحتويات الطراز القديم مقابل فئات الطراز الجديد فئات الطراز القديم فئات جديدة الطراز النوع والفئة تعريف الفصل ديناميكيًا مثال 1 مثال 2 مثال 3 مثال 4 Metaclass مخصص هل هذا حقا ضروري؟ خاتمة يشير مصطلح metaprogramming إلى إمكانية حصول البرنامج على معرفة أو التلاعب بنفسه. تدعم Python شكلاً من أشكال البرمجة الوصفية للفئات تسمى [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d9%85%d9%8a%d8%aa%d8%a7%d9%83%d9%84%d8%a7%d8%b3-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/">ميتاكلاس بايثون</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span style="font-size: 20pt"><strong>جدول المحتويات</strong></span><br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الطراز القديم مقابل فئات الطراز الجديد<br />
فئات الطراز القديم<br />
فئات جديدة الطراز<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">النوع والفئة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تعريف الفصل ديناميكيًا<br />
مثال 1<br />
مثال 2<br />
مثال 3<br />
مثال 4<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">Metaclass مخصص<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هل هذا حقا ضروري؟<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">خاتمة<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يشير مصطلح metaprogramming إلى إمكانية حصول البرنامج على معرفة أو التلاعب بنفسه. تدعم Python شكلاً من أشكال البرمجة الوصفية للفئات تسمى metaclasses.</p>
<p>Metaclasses هي مفهوم OOP مقصور على فئة معينة ، كامنة وراء كل كود Python تقريبًا. أنت تستخدمها سواء كنت على علم بذلك أم لا. بالنسبة للجزء الأكبر ، لا تحتاج إلى أن تكون على دراية بذلك. نادرًا ما يفكر معظم مبرمجي بايثون في الفوقية.</p>
<p>ومع ذلك ، عندما تظهر الحاجة ، توفر Python قدرة لا تدعمها جميع اللغات الموجهة للكائنات: يمكنك الحصول على الغطاء وتحديد الفئات الوصفية المخصصة. يعد استخدام metaclasses المخصص مثيرًا للجدل إلى حد ما ، كما هو مقترح في الاقتباس التالي من Tim Peters ، معلم Python الذي قام بتأليف Zen of Python:<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">&#8220;Metaclasses هي سحر أعمق مما ينبغي أن يقلق بشأنه 99٪ من المستخدمين. إذا كنت تتساءل عما إذا كنت بحاجة إليها ، فأنت لست (الأشخاص الذين يحتاجون إليها بالفعل يعرفون على وجه اليقين أنهم بحاجة إليهم ، ولا يحتاجون إلى تفسير لماذا) &#8220;.</p>
<p>&#8211; تيم بيترز</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هناك Pythonistas (كما هو معروف هواة Python) الذين يعتقدون أنه لا يجب عليك استخدام metaclasses المخصصة. قد يكون هذا بعيدًا بعض الشيء ، ولكن ربما يكون صحيحًا أن الفئات الوصفية المخصصة ليست ضرورية في الغالب. إذا لم يكن من الواضح تمامًا أن المشكلة تستدعيها ، فمن المحتمل أن تكون أنظف وأكثر قابلية للقراءة إذا تم حلها بطريقة أبسط.</p>
<p>ومع ذلك ، فإن فهم Python metaclasses مفيد ، لأنه يؤدي إلى فهم أفضل للداخلية في صفوف Python بشكل عام. أنت لا تعرف أبدًا: قد تجد نفسك يومًا ما في واحدة من تلك المواقف التي تعرف فيها فقط أن metaclass المخصص هو ما تريده.</p>
<p><span style="font-size: 20pt"><strong>الطراز القديم مقابل فئات الطراز الجديد</strong></span></p>
<p>في عالم بايثون ، يمكن أن يكون الفصل واحدًا من نوعين. لم يتم تحديد أي مصطلحات رسمية ، لذلك يشار إليها بشكل غير رسمي على أنها فصول من الطراز القديم والأسلوب الجديد.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>فئات الطراز القديم</strong></p>
<p>في الفصول ذات النمط القديم ، لا يكون الفصل والنوع نفس الشيء تمامًا. يتم دائمًا تنفيذ مثيل لفئة ذات نمط قديم من نوع مضمن واحد يسمى مثيل. إذا كان obj مثيلًا لفئة ذات نمط قديم ، فإن obj .__ class__ تحدد الفئة ، لكن النوع (obj) هو دائمًا مثيل. المثال التالي مأخوذ من Python 2.7:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="vm">__class__</span>
<span class="go">&lt;class __main__.Foo at 0x000000000535CC48&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="go">&lt;type 'instance'&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>فئات جديدة الطراز</strong></p>
<p>توحد الفصول ذات النمط الجديد مفاهيم الفئة والنوع. إذا كان obj مثيلًا لفئة ذات نمط جديد ، فإن النوع (obj) هو نفسه obj .__ class__:<br />
</span></p>
<div class="highlight python repl">
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="vm">__class__</span>
<span class="go">&lt;class '__main__.Foo'&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
<span class="go">&lt;class '__main__.Foo'&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">obj</span><span class="o">.</span><span class="vm">__class__</span> <span class="ow">is</span> <span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>
<span class="go">True</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">n</span> <span class="o">=</span> <span class="mi">5</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">d</span> <span class="o">=</span> <span class="p">{</span> <span class="s1">'x'</span> <span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="s1">'y'</span> <span class="p">:</span> <span class="mi">2</span> <span class="p">}</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">obj</span> <span class="ow">in</span> <span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span> <span class="ow">is</span> <span class="n">obj</span><span class="o">.</span><span class="vm">__class__</span><span class="p">)</span>
<span class="gp">...</span>
<span class="go">True</span>
<span class="go">True</span>
<span class="go">True</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">النوع والفئة</span></strong></p>
<p>في Python 3 ، كل الفئات هي فئات جديدة. وبالتالي ، في Python 3 ، من المعقول الإشارة إلى نوع الكائن وفئته بالتبادل.<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ملاحظة: في Python 2 ، تكون الفئات هي النمط القديم افتراضيًا. قبل Python 2.2 ، لم تكن الفئات ذات النمط الجديد مدعومة على الإطلاق. من Python 2.2 فصاعدًا ، يمكن إنشاؤها ولكن يجب الإعلان عنها صراحة على أنها نمط جديد.</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تذكر أن كل شيء في بايثون هو كائن. الفئات هي كائنات أيضًا. نتيجة لذلك ، يجب أن يكون للفصل نوع. ما هو نوع الفصل؟</p>
<p>ضع في اعتبارك ما يلي:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>

<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
<span class="go">&lt;class '__main__.Foo'&gt;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">Foo</span><span class="p">)</span>
<span class="go">&lt;class 'type'&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">نوع x هو فئة Foo ، كما تتوقع. لكن نوع Foo ، الفئة نفسها ، هي النوع. بشكل عام ، نوع أي فئة ذات نمط جديد هو النوع.</p>
<p>نوع الفصول المضمنة التي تعرفها هو أيضًا نوع:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">for</span> <span class="n">t</span> <span class="ow">in</span> <span class="nb">int</span><span class="p">,</span> <span class="nb">float</span><span class="p">,</span> <span class="nb">dict</span><span class="p">,</span> <span class="nb">list</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">:</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="nb">type</span><span class="p">(</span><span class="n">t</span><span class="p">))</span>
<span class="gp">...</span>
<span class="go">&lt;class 'type'&gt;</span>
<span class="go">&lt;class 'type'&gt;</span>
<span class="go">&lt;class 'type'&gt;</span>
<span class="go">&lt;class 'type'&gt;</span>
<span class="go">&lt;class 'type'&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لهذه المسألة ، نوع النوع هو النوع أيضًا (نعم ، حقًا):<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="nb">type</span><span class="p">)</span>
<span class="go">&lt;class 'type'&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">النوع هو metaclass ، والفئات هي أمثلة. تمامًا كما أن الكائن العادي هو مثيل لفئة ، فإن أي فئة ذات نمط جديد في Python ، وبالتالي أي فئة في Python 3 ، هي مثيل من النوع metaclass.</p>
<p>في الحالة أعلاه:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">x هو مثيل للفئة Foo.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">Foo هو مثيل من النوع metaclass.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">النوع هو أيضًا مثيل من النوع metaclass ، لذا فهو مثيل لنفسه.<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span style="font-size: 20pt"><strong>تعريف الفصل ديناميكيًا</strong></span></p>
<p>دالة type () المضمنة ، عند تمرير وسيطة واحدة ، ترجع نوع الكائن. بالنسبة لفئات النمط الجديد ، يكون هذا بشكل عام هو نفسه سمة __class__ للكائن:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
<span class="go">&lt;class 'int'&gt;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">([</span><span class="s1">'foo'</span><span class="p">,</span> <span class="s1">'bar'</span><span class="p">,</span> <span class="s1">'baz'</span><span class="p">])</span>
<span class="go">&lt;class 'list'&gt;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">t</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">t</span><span class="p">)</span>
<span class="go">&lt;class 'tuple'&gt;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">Foo</span><span class="p">())</span>
<span class="go">&lt;class '__main__.Foo'&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكنك أيضًا استدعاء النوع () بثلاث وسيطات &#8211; النوع (&lt;name&gt; ، &lt;bases&gt; ، &lt;dct&gt;):<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">&lt;name&gt; يحدد اسم الفئة. تصبح هذه سمة __name__ للفئة.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يحدد &lt;bases&gt; مجموعة من الفئات الأساسية التي ترث منها الفئة. تصبح هذه السمة __bases__ للفصل.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يحدد &lt;dct&gt; قاموس مساحة اسم يحتوي على تعريفات لجسم الفئة. تصبح هذه سمة __dict__ للطبقة.<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يؤدي استدعاء type () بهذه الطريقة إلى إنشاء مثيل جديد من النوع metaclass. بمعنى آخر ، يتم إنشاء فئة جديدة ديناميكيًا.</p>
<p>في كل من الأمثلة التالية ، يُعرِّف المقتطف العلوي فئة ديناميكيًا بالنوع () ، بينما يُعرِّف المقتطف أدناه الفئة بالطريقة المعتادة ، باستخدام عبارة الفئة. في كل حالة ، المقتطفان متكافئان وظيفيًا.<br />
</span></p>
<p><strong><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">مثال </span></strong><strong><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">1</span></strong></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في هذا المثال الأول ، تكون الوسيطات &lt;bases&gt; و &lt;dct&gt; التي تم تمريرها إلى النوع () فارغة. لم يتم تحديد وراثة من أي فئة أصل ، ولا يتم وضع أي شيء مبدئيًا في قاموس مساحة الاسم. هذا هو أبسط تعريف ممكن للفئة:<br />
</span></p>
<div class="highlight python repl">
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">Foo</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="s1">'Foo'</span><span class="p">,</span> <span class="p">(),</span> <span class="p">{})</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span>
<span class="go">&lt;__main__.Foo object at 0x04CFAD50&gt;</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span>
<span class="go">&lt;__main__.Foo object at 0x0370AD50&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>مثال 2</strong></p>
<p>هنا ، &lt;bases&gt; عبارة عن مجموعة تحتوي على عنصر واحد Foo ، تحدد الفئة الرئيسية التي يرث Bar منها. يتم وضع السمة ، Attr ، في البداية في قاموس مساحة الاسم:<br />
</span></p>
<div class="highlight python repl">
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">Bar</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="s1">'Bar'</span><span class="p">,</span> <span class="p">(</span><span class="n">Foo</span><span class="p">,),</span> <span class="nb">dict</span><span class="p">(</span><span class="n">attr</span><span class="o">=</span><span class="mi">100</span><span class="p">))</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Bar</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="vm">__class__</span>
<span class="go">&lt;class '__main__.Bar'&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__bases__</span>
<span class="go">(&lt;class '__main__.Foo'&gt;,)</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Bar</span><span class="p">(</span><span class="n">Foo</span><span class="p">):</span>
<span class="gp">... </span>    <span class="n">attr</span> <span class="o">=</span> <span class="mi">100</span>
<span class="gp">...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Bar</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="vm">__class__</span>
<span class="go">&lt;class '__main__.Bar'&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__bases__</span>
<span class="go">(&lt;class '__main__.Foo'&gt;,)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>مثال 3</strong></p>
<p>هذه المرة ، أصبحت &lt;bases&gt; فارغة مرة أخرى. يتم وضع كائنين في قاموس مساحة الاسم عبر الوسيطة &lt;dct&gt;. الأول هو سمة تسمى attr والثاني وظيفة تسمى attr_val ، والتي تصبح طريقة للفئة المحددة:<br />
</span></p>
<div class="highlight python repl">
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">Foo</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span>
<span class="gp">... </span>    <span class="s1">'Foo'</span><span class="p">,</span>
<span class="gp">... </span>    <span class="p">(),</span>
<span class="gp">... </span>    <span class="p">{</span>
<span class="gp">... </span>        <span class="s1">'attr'</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
<span class="gp">... </span>        <span class="s1">'attr_val'</span><span class="p">:</span> <span class="k">lambda</span> <span class="n">x</span> <span class="p">:</span> <span class="n">x</span><span class="o">.</span><span class="n">attr</span>
<span class="gp">... </span>    <span class="p">}</span>
<span class="gp">... </span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="n">attr_val</span><span class="p">()</span>
<span class="go">100</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">attr</span> <span class="o">=</span> <span class="mi">100</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="nf">attr_val</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">attr</span>
<span class="gp">...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="n">attr_val</span><span class="p">()</span>
<span class="go">100</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>مثال 4</strong></p>
<p>يمكن تعريف الوظائف البسيطة جدًا فقط باستخدام lambda في Python. في المثال التالي ، يتم تعريف دالة أكثر تعقيدًا من الخارج ثم يتم تعيينها إلى attr_val في قاموس مساحة الاسم عبر الاسم f:<br />
</span></p>
<div class="highlight python repl">
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">'attr ='</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">attr</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Foo</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span>
<span class="gp">... </span>    <span class="s1">'Foo'</span><span class="p">,</span>
<span class="gp">... </span>    <span class="p">(),</span>
<span class="gp">... </span>    <span class="p">{</span>
<span class="gp">... </span>        <span class="s1">'attr'</span><span class="p">:</span> <span class="mi">100</span><span class="p">,</span>
<span class="gp">... </span>        <span class="s1">'attr_val'</span><span class="p">:</span> <span class="n">f</span>
<span class="gp">... </span>    <span class="p">}</span>
<span class="gp">... </span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="n">attr_val</span><span class="p">()</span>
<span class="go">attr = 100</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">obj</span><span class="p">):</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">'attr ='</span><span class="p">,</span> <span class="n">obj</span><span class="o">.</span><span class="n">attr</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">attr</span> <span class="o">=</span> <span class="mi">100</span>
<span class="gp">... </span>    <span class="n">attr_val</span> <span class="o">=</span> <span class="n">f</span>
<span class="gp">...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="n">attr_val</span><span class="p">()</span>
<span class="go">attr = 100</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">Metaclass مخصص</span></strong></p>
<p>ضع في اعتبارك مرة أخرى هذا المثال البالي:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">f</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ينشئ التعبير Foo () مثيلًا جديدًا للفئة Foo. عندما يواجه المترجم Foo () ، يحدث ما يلي:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يتم استدعاء طريقة __call __ () لفئة Foo الرئيسية. نظرًا لأن Foo هي فئة نمطية جديدة قياسية ، فإن صنفها الرئيسي هو النوع metaclass ، لذلك يتم استدعاء طريقة type’s __call __ ().
<p></span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تستدعي طريقة __call __ () هذه بدورها ما يلي:<br />
__جديد__()<br />
__فيه__()<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا لم يعرّف Foo __new __ () و __init __ () ، يتم توريث الطرق الافتراضية من أصل Foo. ولكن إذا حدد Foo هذه الأساليب ، فإنها تلغي تلك الموجودة في الأصل ، مما يسمح بسلوك مخصص عند إنشاء مثيل Foo.</p>
<p>في ما يلي ، يتم تعريف طريقة مخصصة تسمى new () وتعيينها على أنها طريقة __new __ () لـ Foo:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">new</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
<span class="gp">... </span>    <span class="n">x</span> <span class="o">=</span> <span class="nb">object</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
<span class="gp">... </span>    <span class="n">x</span><span class="o">.</span><span class="n">attr</span> <span class="o">=</span> <span class="mi">100</span>
<span class="gp">... </span>    <span class="k">return</span> <span class="n">x</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Foo</span><span class="o">.</span><span class="fm">__new__</span> <span class="o">=</span> <span class="n">new</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">f</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">f</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">g</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">g</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يعدل هذا سلوك إنشاء مثيل للفئة Foo: في كل مرة يتم إنشاء مثيل لـ Foo ، يتم تهيئته افتراضيًا بسمة تسمى attr ، والتي لها قيمة 100. (عادةً ما يظهر رمز مثل هذا في طريقة __init __ () وليس عادةً في __new __ (). تم إنشاء هذا المثال لأغراض توضيحية.)</p>
<p>الآن ، كما تم التأكيد عليه بالفعل ، تعتبر الفئات كائنات أيضًا. لنفترض أنك أردت تخصيص سلوك إنشاء مثيل بشكل مشابه عند إنشاء فئة مثل Foo. إذا كنت ستتبع النمط أعلاه ، فعليك مرة أخرى تحديد طريقة مخصصة وتعيينها على أنها طريقة __new __ () للفئة التي يمثل Foo مثيلًا لها. Foo هو مثيل من النوع metaclass ، لذلك تبدو الشفرة كما يلي:<br />
</span></p>
<pre><code><span class="go"># Spoiler alert:  This doesn't work!</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">new</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
<span class="gp">... </span>    <span class="n">x</span> <span class="o">=</span> <span class="nb">type</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">)</span>
<span class="gp">... </span>    <span class="n">x</span><span class="o">.</span><span class="n">attr</span> <span class="o">=</span> <span class="mi">100</span>
<span class="gp">... </span>    <span class="k">return</span> <span class="n">x</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="o">.</span><span class="fm">__new__</span> <span class="o">=</span> <span class="n">new</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">"&lt;pyshell#77&gt;"</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
    <span class="nb">type</span><span class="o">.</span><span class="fm">__new__</span> <span class="o">=</span> <span class="n">new</span>
<span class="gr">TypeError</span>: <span class="n">can't set attributes of built-in/extension type 'type'</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">باستثناء ، كما ترى ، لا يمكنك إعادة تعيين طريقة __new __ () من النوع metaclass. بايثون لا تسمح بذلك.</p>
<p>ربما هذا فقط كذلك. النوع هو metaclass الذي يتم اشتقاق منه جميع فئات النمط الجديد. لا ينبغي أن تتلاعب بها على أي حال. ولكن بعد ذلك ما هو الملاذ الموجود ، إذا كنت تريد تخصيص مثيل فئة؟</p>
<p>أحد الحلول الممكنة هو metaclass مخصص. بشكل أساسي ، بدلاً من الالتفاف حول النوع metaclass ، يمكنك تحديد metaclass الخاص بك ، والذي يشتق من الكتابة ، ومن ثم يمكنك التخلص منه بدلاً من ذلك.</p>
<p>الخطوة الأولى هي تحديد metaclass المشتق من الكتابة ، على النحو التالي:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Meta</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">dct</span><span class="p">):</span>
<span class="gp">... </span>        <span class="n">x</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__new__</span><span class="p">(</span><span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">dct</span><span class="p">)</span>
<span class="gp">... </span>        <span class="n">x</span><span class="o">.</span><span class="n">attr</span> <span class="o">=</span> <span class="mi">100</span>
<span class="gp">... </span>        <span class="k">return</span> <span class="n">x</span>
<span class="gp">...</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">فئة رأس التعريف Meta (type): تحدد أن Meta مشتق من النوع. نظرًا لأن الكتابة هي metaclass ، فهذا يجعل Meta metaclass أيضًا.</p>
<p>لاحظ أنه تم تعريف طريقة __new __ () المخصصة للميتا. لم يكن من الممكن القيام بذلك على نوع metaclass مباشرة. تقوم طريقة __new __ () بما يلي:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">المفوضين عبر () super إلى طريقة __new __ () الخاصة بالفئة الوصفية الأصلية (النوع) لإنشاء فصل دراسي جديد بالفعل<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يعيّن سمة السمة المخصصة للفئة بقيمة 100<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إرجاع الفصل الذي تم إنشاؤه حديثًا<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الآن النصف الآخر من الشعوذة: حدد فئة جديدة Foo وحدد أن metaclass الخاص بها هو Metaclass Meta المخصص ، بدلاً من نوع metaclass القياسي. يتم ذلك باستخدام الكلمة الأساسية metaclass في تعريف الفئة على النحو التالي:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">(</span><span class="n">metaclass</span><span class="o">=</span><span class="n">Meta</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Foo</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هاهو! اختار Foo سمة Attr تلقائيًا من Meta metaclass. بالطبع ، أي فئات أخرى تحددها بالمثل ستفعل الشيء نفسه:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Bar</span><span class="p">(</span><span class="n">metaclass</span><span class="o">=</span><span class="n">Meta</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Qux</span><span class="p">(</span><span class="n">metaclass</span><span class="o">=</span><span class="n">Meta</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Bar</span><span class="o">.</span><span class="n">attr</span><span class="p">,</span> <span class="n">Qux</span><span class="o">.</span><span class="n">attr</span>
<span class="go">(100, 100)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بالطريقة نفسها التي يعمل بها الفصل كقالب لإنشاء الكائنات ، يعمل metaclass كقالب لإنشاء الفئات. يشار إلى Metaclasses أحيانًا بمصانع الطبقة.</p>
<p>قارن بين المثالين التاليين:</p>
<p><strong>مصنع الكائن:</strong><br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="gp">... </span>        <span class="bp">self</span><span class="o">.</span><span class="n">attr</span> <span class="o">=</span> <span class="mi">100</span>
<span class="gp">...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">y</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">y</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">z</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">z</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>مصنع كلاس:</strong><br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Meta</span><span class="p">(</span><span class="nb">type</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span>
<span class="gp">... </span>        <span class="bp">cls</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">bases</span><span class="p">,</span> <span class="n">dct</span>
<span class="gp">... </span>    <span class="p">):</span>
<span class="gp">... </span>        <span class="bp">cls</span><span class="o">.</span><span class="n">attr</span> <span class="o">=</span> <span class="mi">100</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">X</span><span class="p">(</span><span class="n">metaclass</span><span class="o">=</span><span class="n">Meta</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">X</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Y</span><span class="p">(</span><span class="n">metaclass</span><span class="o">=</span><span class="n">Meta</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Y</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Z</span><span class="p">(</span><span class="n">metaclass</span><span class="o">=</span><span class="n">Meta</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Z</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span style="font-size: 20pt"><strong>هل هذا حقا ضروري؟</strong></span></p>
<p>بسيط مثل مثال مصنع الفئة أعلاه ، فهو جوهر كيفية عمل metaclasses. أنها تسمح بتخصيص إنشاء مثيل للفئة.</p>
<p>ومع ذلك ، هناك الكثير من الجلبة فقط لمنح سمة السمات المخصصة لكل فئة تم إنشاؤها حديثًا. هل تحتاج حقًا إلى metaclass فقط من أجل ذلك؟</p>
<p>في بايثون ، هناك طريقتان أخريان على الأقل يمكن من خلالها تحقيق الشيء نفسه بشكل فعال:</p>
<p><strong>الميراث البسيط:</strong><br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Base</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">attr</span> <span class="o">=</span> <span class="mi">100</span>
<span class="gp">...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">X</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Y</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Z</span><span class="p">(</span><span class="n">Base</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">X</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Y</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Z</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>مصمم فئة:</strong><br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">decorator</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
<span class="gp">... </span>    <span class="k">class</span> <span class="nc">NewClass</span><span class="p">(</span><span class="bp">cls</span><span class="p">):</span>
<span class="gp">... </span>        <span class="n">attr</span> <span class="o">=</span> <span class="mi">100</span>
<span class="gp">... </span>    <span class="k">return</span> <span class="n">NewClass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nd">@decorator</span>
<span class="gp">... </span><span class="k">class</span> <span class="nc">X</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nd">@decorator</span>
<span class="gp">... </span><span class="k">class</span> <span class="nc">Y</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nd">@decorator</span>
<span class="gp">... </span><span class="k">class</span> <span class="nc">Z</span><span class="p">:</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">X</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Y</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Z</span><span class="o">.</span><span class="n">attr</span>
<span class="go">100</span>
</code></pre>
<p><strong><span class="tlid-translation translation" lang="ar" style="font-size: 20pt">خاتمة</span></strong></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span title="">كما يقترح تيم بيترز ، يمكن أن تنحرف الطبقات الوصفية بسهولة إلى عالم كونها &#8220;حل بحثًا عن مشكلة&#8221;.</span> <span title="">ليس من الضروري عادةً إنشاء فئات وصفية مخصصة.</span> <span class="" title="">إذا كان من الممكن حل المشكلة المطروحة بطريقة أبسط ، فمن المحتمل أن تكون كذلك.</span> <span class="" title="">ومع ذلك ، من المفيد فهم الفصول الوصفية بحيث تفهم فئات بايثون بشكل عام ويمكن أن تتعرف على ما إذا كانت metaclass هي الأداة المناسبة للاستخدام.</span></span></p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d9%85%d9%8a%d8%aa%d8%a7%d9%83%d9%84%d8%a7%d8%b3-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/">ميتاكلاس بايثون</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://arabdars.com/%d9%85%d9%8a%d8%aa%d8%a7%d9%83%d9%84%d8%a7%d8%b3-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>استثناءات بايثون: مقدمة</title>
		<link>https://arabdars.com/%d8%a7%d8%b3%d8%aa%d8%ab%d9%86%d8%a7%d8%a1%d8%a7%d8%aa-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-%d9%85%d9%82%d8%af%d9%85%d8%a9/</link>
					<comments>https://arabdars.com/%d8%a7%d8%b3%d8%aa%d8%ab%d9%86%d8%a7%d8%a1%d8%a7%d8%aa-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-%d9%85%d9%82%d8%af%d9%85%d8%a9/#respond</comments>
		
		<dc:creator><![CDATA[Reyhane]]></dc:creator>
		<pubDate>Mon, 21 Sep 2020 16:10:20 +0000</pubDate>
				<category><![CDATA[الماتلاب Matlab]]></category>
		<guid isPermaLink="false">https://arabdars.com/?p=1628</guid>

					<description><![CDATA[<p>جدول المحتويات الاستثناءات مقابل الأخطاء النحوية رفع استثناء استثناء AssertionError كتلة المحاولة والاستثناء: معالجة الاستثناءات شرط آخر التنظيف بعد الاستخدام أخيرًا تلخيص لما سبق ينتهي برنامج بايثون بمجرد أن يواجه خطأ. في Python ، يمكن أن يكون الخطأ خطأ نحويًا أو استثناءً. في هذه المقالة ، سترى ما هو الاستثناء وكيف يختلف عن الخطأ النحوي. [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d8%a7%d8%b3%d8%aa%d8%ab%d9%86%d8%a7%d8%a1%d8%a7%d8%aa-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-%d9%85%d9%82%d8%af%d9%85%d8%a9/">استثناءات بايثون: مقدمة</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">جدول المحتويات</span></strong><br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الاستثناءات مقابل الأخطاء النحوية<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">رفع استثناء<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">استثناء AssertionError<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كتلة المحاولة والاستثناء: معالجة الاستثناءات<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">شرط آخر<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">التنظيف بعد الاستخدام أخيرًا<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تلخيص لما سبق<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ينتهي برنامج بايثون بمجرد أن يواجه خطأ. في Python ، يمكن أن يكون الخطأ خطأ نحويًا أو استثناءً. في هذه المقالة ، سترى ما هو الاستثناء وكيف يختلف عن الخطأ النحوي. بعد ذلك ، ستتعرف على كيفية رفع الاستثناءات وتقديم التأكيدات. بعد ذلك ، ستنتهي مع عرض توضيحي لمحاولة الاستثناء.<br />
</span></p>
<p><a href="https://files.realpython.com/media/intro.8915db1758d8.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/intro.8915db1758d8.png" alt="An introduction to exceptions in Python" width="1394" height="411" /></a></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">الاستثناءات مقابل الأخطاء النحوية</span></strong></p>
<p>تحدث أخطاء بناء الجملة عندما يكتشف المحلل اللغوي عبارة غير صحيحة. لاحظ المثال التالي:<br />
</span></p>
<pre><code><span class="x">&gt;&gt;&gt; print( 0 / 0 ))</span>
  File <span class="nb">"&lt;stdin&gt;"</span>, line <span class="m">1</span>
    <span class="nb">print</span><span class="p">(</span> <span class="mi">0</span> <span class="o">/</span> <span class="mi">0</span> <span class="p">))</span>
                  <span class="o">^</span>
<span class="gr">SyntaxError</span>: <span class="n">invalid syntax</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يشير السهم إلى مكان تعرض المحلل اللغوي لخطأ في بناء الجملة. في هذا المثال ، كان هناك قوس واحد أكثر من اللازم. قم بإزالته وتشغيل الكود الخاص بك مرة أخرى:<br />
</span></p>
<pre><code><span class="x">&gt;&gt;&gt; print( 0 / 0)</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">"&lt;stdin&gt;"</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">ZeroDivisionError</span>: <span class="n">integer division or modulo by zero</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هذه المرة ، واجهت خطأ استثناء. يحدث هذا النوع من الأخطاء عندما ينتج عن رمز Python الصحيح من الناحية التركيبية خطأ. أشار السطر الأخير من الرسالة إلى نوع خطأ الاستثناء الذي واجهته.</p>
<p>بدلاً من إظهار خطأ استثناء الرسالة ، توضح Python نوع خطأ الاستثناء الذي تمت مواجهته. في هذه الحالة ، كان خطأ ZeroDivisionError. تأتي Python مع العديد من الاستثناءات المضمنة بالإضافة إلى إمكانية إنشاء استثناءات محددة ذاتيًا.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">رفع استثناء</span></strong></p>
<p>يمكننا استخدام الزيادة لطرح استثناء في حالة حدوث شرط. يمكن استكمال البيان مع استثناء مخصص.<br />
</span></p>
<p><a href="https://files.realpython.com/media/raise.3931e8819e08.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/raise.3931e8819e08.png" alt="Illustration of  raise statement usage" width="1394" height="311" /></a></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا كنت تريد إلقاء خطأ عند حدوث حالة معينة باستخدام الزيادة ، فيمكنك القيام بذلك على النحو التالي:<br />
</span></p>
<pre><code><span class="n">x</span> <span class="o">=</span> <span class="mi">10</span>
<span class="k">if</span> <span class="n">x</span> <span class="o">&gt;</span> <span class="mi">5</span><span class="p">:</span>
    <span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s1">'x should not exceed 5. The value of x was: </span><span class="si">{}</span><span class="s1">'</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">x</span><span class="p">))</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عند تشغيل هذا الرمز ، سيكون الإخراج كما يلي:<br />
</span></p>
<pre><code><span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">"&lt;input&gt;"</span>, line <span class="m">4</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">Exception</span>: <span class="n">x should not exceed 5. The value of x was: 10</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">توقف البرنامج وعرض استثناءنا على الشاشة ، مع تقديم أدلة حول الخطأ الذي حدث.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">استثناء AssertionError</span></strong></p>
<p>بدلاً من انتظار تعطل البرنامج في منتصف الطريق ، يمكنك أيضًا البدء بتأكيد في Python. نؤكد أنه تم استيفاء شرط معين. إذا تبين أن هذا الشرط صحيح ، فهذا ممتاز! يمكن أن يستمر البرنامج. إذا تبين أن الشرط خاطئ ، فيمكنك جعل البرنامج يطرح استثناء AssertionError.<br />
</span></p>
<p><a href="https://files.realpython.com/media/assert.f6d344f0c0b4.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/assert.f6d344f0c0b4.png" alt="Python assert statement" width="1394" height="411" /></a><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ألق نظرة على المثال التالي ، حيث تم التأكيد على أن الكود سيتم تنفيذه على نظام Linux:<br />
</span></p>
<pre><code><span class="kn">import</span> <span class="nn">sys</span>
<span class="k">assert</span> <span class="p">(</span><span class="s1">'linux'</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">platform</span><span class="p">),</span> <span class="s2">"This code runs on Linux only."</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا قمت بتشغيل هذا الرمز على جهاز Linux ، فسيتم تمرير التأكيد. إذا كنت ستقوم بتشغيل هذا الرمز على جهاز يعمل بنظام Windows ، فستكون نتيجة التأكيد False وستكون النتيجة كما يلي:<br />
</span></p>
<pre><code><span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">"&lt;input&gt;"</span>, line <span class="m">2</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">AssertionError</span>: <span class="n">This code runs on Linux only.</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في هذا المثال ، يعد طرح استثناء AssertionError هو آخر شيء سيفعله البرنامج. سيتوقف البرنامج ولن يستمر. ماذا لو لم يكن هذا ما تريده؟</p>
<p><strong><span style="font-size: 20pt">كتلة المحاولة والاستثناء: معالجة الاستثناءات</span></strong></p>
<p>تُستخدم كتلة try and except في Python للقبض على الاستثناءات ومعالجتها. تنفذ Python التعليمات البرمجية التي تلي تعليمة try كجزء &#8220;عادي&#8221; من البرنامج. الكود الذي يتبع تعليمة الاستثناء هو استجابة البرنامج لأي استثناءات في عبارة try السابقة.<br />
</span></p>
<p><a href="https://files.realpython.com/media/try_except.c94eabed2c59.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/try_except.c94eabed2c59.png" alt="Diagram showing try and except statements" width="1394" height="556" /></a><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كما رأيت سابقًا ، عندما تصطدم الشفرة الصحيحة من الناحية التركيبية بخطأ ، فإن Python ستطلق خطأ استثناء. سيؤدي خطأ الاستثناء هذا إلى تعطل البرنامج إذا لم تتم معالجته. يحدد بند الاستثناء كيف يستجيب برنامجك للاستثناءات.</p>
<p>يمكن أن تساعدك الوظيفة التالية في فهم كتلة المحاولة والاستثناء:<br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">linux_interaction</span><span class="p">():</span>
    <span class="k">assert</span> <span class="p">(</span><span class="s1">'linux'</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">platform</span><span class="p">),</span> <span class="s2">"Function can only run on Linux systems."</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'Doing something.'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن تشغيل linux_interaction () على نظام Linux فقط. سوف يطرح التأكيد في هذه الوظيفة استثناء AssertionError إذا قمت باستدعائه على نظام تشغيل آخر غير Linux.</p>
<p>يمكنك تجربة الوظيفة باستخدام الكود التالي:<br />
</span></p>
<pre><code><span class="k">try</span><span class="p">:</span>
    <span class="n">linux_interaction</span><span class="p">()</span>
<span class="k">except</span><span class="p">:</span>
    <span class="k">pass</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الطريقة التي تعاملت بها مع الخطأ هنا هي بتسليمك تمريرة. إذا كنت ستقوم بتشغيل هذا الرمز على جهاز يعمل بنظام Windows ، فستحصل على الإخراج التالي:</p>
<p>ليس لديك شيء. الشيء الجيد هنا هو أن البرنامج لم يتعطل. ولكن سيكون من الجيد معرفة ما إذا كان هناك نوع من الاستثناء يحدث عندما قمت بتشغيل الكود الخاص بك. لتحقيق هذه الغاية ، يمكنك تغيير البطاقة إلى شيء من شأنه أن يولد رسالة إعلامية ، مثل:<br />
</span></p>
<pre><code><span class="k">try</span><span class="p">:</span>
    <span class="n">linux_interaction</span><span class="p">()</span>
<span class="k">except</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'Linux function was not executed'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">قم بتنفيذ هذا الرمز على جهاز يعمل بنظام Windows:<br />
</span></p>
<pre><code><span class="go">Linux function was not executed</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عند حدوث استثناء في برنامج يقوم بتشغيل هذه الوظيفة ، سيستمر البرنامج بالإضافة إلى إبلاغك بحقيقة أن استدعاء الوظيفة لم يكن ناجحًا.</p>
<p>ما لم تراه هو نوع الخطأ الذي تم إلقاؤه نتيجة لاستدعاء الوظيفة. لكي ترى الخطأ الذي حدث بالضبط ، ستحتاج إلى اكتشاف الخطأ الذي أحدثته الوظيفة.</p>
<p>الكود التالي هو مثال حيث يمكنك التقاط AssertionError وإخراج تلك الرسالة إلى الشاشة:<br />
</span></p>
<pre><code><span class="k">try</span><span class="p">:</span>
    <span class="n">linux_interaction</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">AssertionError</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">error</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'The linux_interaction() function was not executed'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يؤدي تشغيل هذه الوظيفة على جهاز يعمل بنظام Windows إلى ما يلي:<br />
</span></p>
<pre><code><span class="go">Function can only run on Linux systems.</span>
<span class="go">The linux_interaction() function was not executed</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الرسالة الأولى هي AssertionError ، تخبرك أنه لا يمكن تنفيذ الوظيفة إلا على جهاز Linux. تخبرك الرسالة الثانية بالوظيفة التي لم يتم تنفيذها.</p>
<p>في المثال السابق ، قمت باستدعاء دالة كتبتها بنفسك. عند تنفيذ الوظيفة ، اكتشفت استثناء AssertionError وطباعته على الشاشة.</p>
<p>إليك مثال آخر حيث تفتح ملفًا وتستخدم استثناءًا مضمنًا:</span></p>
<pre><code><span class="k">try</span><span class="p">:</span>
    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'file.log'</span><span class="p">)</span> <span class="k">as</span> <span class="n">file</span><span class="p">:</span>
        <span class="n">read_data</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="k">except</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'Could not open file.log'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا لم يكن file.log موجودًا ، فستخرج كتلة التعليمات البرمجية هذه ما يلي:<br />
</span></p>
<pre><code><span class="go">Could not open file.log</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هذه رسالة إعلامية ، وسيستمر تشغيل برنامجنا. في مستندات Python ، يمكنك أن ترى أن هناك الكثير من الاستثناءات المضمنة التي يمكنك استخدامها هنا. الاستثناء الوحيد الموضح في تلك الصفحة هو ما يلي:<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">استثناء FileNotFoundError</p>
<p>يُطلق عند طلب ملف أو دليل ولكنه غير موجود. يتوافق مع errno ENOENT.</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">للقبض على هذا النوع من الاستثناءات وطباعته على الشاشة ، يمكنك استخدام الكود التالي:<br />
</span></p>
<pre><code><span class="k">try</span><span class="p">:</span>
    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'file.log'</span><span class="p">)</span> <span class="k">as</span> <span class="n">file</span><span class="p">:</span>
        <span class="n">read_data</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">FileNotFoundError</span> <span class="k">as</span> <span class="n">fnf_error</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">fnf_error</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في هذه الحالة ، إذا لم يكن file.log موجودًا ، فسيكون الإخراج كما يلي:<br />
</span></p>
<pre><code><span class="go">[Errno 2] No such file or directory: 'file.log'</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن أن يكون لديك أكثر من استدعاء دالة في جملة try وتوقع اصطياد استثناءات مختلفة. الشيء الذي يجب ملاحظته هنا هو أن الكود في جملة try سيتوقف بمجرد مواجهة استثناء.<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تحذير: Catching Exception يخفي كل الأخطاء &#8230; حتى تلك غير المتوقعة تمامًا. هذا هو السبب في أنه يجب عليك تجنب البنود العارية باستثناء البنود في برامج بايثون الخاصة بك. بدلاً من ذلك ، سترغب في الرجوع إلى فئات استثناء محددة تريد التقاطها والتعامل معها. يمكنك معرفة المزيد حول سبب اعتبار هذه فكرة جيدة في هذا البرنامج التعليمي.</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">انظر إلى الكود التالي. هنا ، تقوم أولاً باستدعاء الدالة linux_interaction () ثم تحاول فتح ملف:<br />
</span></p>
<pre><code><span class="k">try</span><span class="p">:</span>
    <span class="n">linux_interaction</span><span class="p">()</span>
    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'file.log'</span><span class="p">)</span> <span class="k">as</span> <span class="n">file</span><span class="p">:</span>
        <span class="n">read_data</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">FileNotFoundError</span> <span class="k">as</span> <span class="n">fnf_error</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">fnf_error</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">AssertionError</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">error</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'Linux linux_interaction() function was not executed'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا لم يكن الملف موجودًا ، فسيؤدي تشغيل هذا الرمز على جهاز يعمل بنظام Windows إلى إخراج ما يلي:<br />
</span></p>
<pre><code><span class="go">Function can only run on Linux systems.</span>
<span class="go">Linux linux_interaction() function was not executed</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">داخل جملة try ، واجهت استثناء على الفور ولم تصل إلى الجزء الذي تحاول فيه فتح file.log. انظر الآن إلى ما يحدث عند تشغيل الكود على جهاز Linux:<br />
</span></p>
<pre><code><span class="go">[Errno 2] No such file or directory: 'file.log'</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">فيما يلي النقاط الرئيسية:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يتم تنفيذ جملة محاولة حتى النقطة التي يتم فيها مواجهة الاستثناء الأول.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">داخل بند الاستثناء ، أو معالج الاستثناء ، يمكنك تحديد كيفية استجابة البرنامج للاستثناء.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكنك توقع استثناءات متعددة والتمييز بين كيفية استجابة البرنامج لها.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تجنب استخدام العارية باستثناء الجمل.<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">شرط آخر</span></strong></p>
<p>في Python ، باستخدام تعليمة else ، يمكنك توجيه برنامج لتنفيذ كتلة معينة من التعليمات البرمجية فقط في حالة عدم وجود استثناءات.<br />
</span></p>
<p><a href="https://files.realpython.com/media/try_except_else.703aaeeb63d3.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/try_except_else.703aaeeb63d3.png" alt="Diagram of try, except, and else statements in Python" width="1394" height="783" /></a><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ننظر إلى المثال التالي:<br />
</span></p>
<pre><code><span class="k">try</span><span class="p">:</span>
    <span class="n">linux_interaction</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">AssertionError</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">error</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'Executing the else clause.'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا كنت ستقوم بتشغيل هذا الرمز على نظام Linux ، فسيكون الإخراج كما يلي:<br />
</span></p>
<pre><code><span class="go">Doing something.</span>
<span class="go">Executing the else clause.</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">نظرًا لأن البرنامج لم يتم تشغيله في أي استثناءات ، تم تنفيذ جملة else.</p>
<p>يمكنك أيضًا محاولة تشغيل التعليمات البرمجية داخل جملة else والتقاط الاستثناءات المحتملة هناك أيضًا:<br />
</span></p>
<pre><code><span class="k">try</span><span class="p">:</span>
    <span class="n">linux_interaction</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">AssertionError</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">error</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'file.log'</span><span class="p">)</span> <span class="k">as</span> <span class="n">file</span><span class="p">:</span>
            <span class="n">read_data</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
    <span class="k">except</span> <span class="ne">FileNotFoundError</span> <span class="k">as</span> <span class="n">fnf_error</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">fnf_error</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا كنت ستقوم بتنفيذ هذا الرمز على جهاز Linux ، فستحصل على النتيجة التالية:<br />
</span></p>
<pre><code><span class="go">Doing something.</span>
<span class="go">[Errno 2] No such file or directory: 'file.log'</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">من الإخراج ، يمكنك أن ترى أن وظيفة linux_interaction () تعمل. بسبب عدم وجود استثناءات ، تم إجراء محاولة لفتح file.log. هذا الملف غير موجود ، وبدلاً من فتح الملف ، اكتشفت استثناء FileNotFoundError.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">التنظيف بعد الاستخدام أخيرًا</span></strong></p>
<p>تخيل أنه كان عليك دائمًا تنفيذ نوع من الإجراءات للتنظيف بعد تنفيذ التعليمات البرمجية الخاصة بك. تمكنك لغة بايثون من القيام بذلك باستخدام الجملة النهائية.<br />
</span></p>
<p><a href="https://files.realpython.com/media/try_except_else_finally.a7fac6c36c55.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/try_except_else_finally.a7fac6c36c55.png" alt="Diagram explaining try except else finally statements" width="1394" height="1000" /></a></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ألق نظرة على المثال التالي:<br />
</span></p>
<pre><code><span class="k">try</span><span class="p">:</span>
    <span class="n">linux_interaction</span><span class="p">()</span>
<span class="k">except</span> <span class="ne">AssertionError</span> <span class="k">as</span> <span class="n">error</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">error</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
    <span class="k">try</span><span class="p">:</span>
        <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'file.log'</span><span class="p">)</span> <span class="k">as</span> <span class="n">file</span><span class="p">:</span>
            <span class="n">read_data</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
    <span class="k">except</span> <span class="ne">FileNotFoundError</span> <span class="k">as</span> <span class="n">fnf_error</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">fnf_error</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'Cleaning up, irrespective of any exceptions.'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في الكود السابق ، سيتم تنفيذ كل شيء في الجملة النهائية. لا يهم إذا واجهت استثناء في مكان ما في جمل try أو else. سيؤدي تشغيل الكود السابق على جهاز يعمل بنظام Windows إلى إخراج ما يلي:<br />
</span></p>
<pre><code><span class="go">Function can only run on Linux systems.</span>
<span class="go">Cleaning up, irrespective of any exceptions.</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">تلخيص لما سبق</span></strong></p>
<p>بعد رؤية الفرق بين أخطاء بناء الجملة والاستثناءات ، تعلمت طرقًا مختلفة لرفع الاستثناءات والتقاطها والتعامل معها في Python. في هذه المقالة ، رأيت الخيارات التالية:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يسمح لك رفع استثناء في أي وقت.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكنك التأكيد من التحقق مما إذا تم استيفاء شرط معين ورمي استثناء إذا لم يكن كذلك.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في جملة try ، يتم تنفيذ جميع العبارات حتى يتم مواجهة استثناء.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يتم استخدام ما عدا لالتقاط ومعالجة الاستثناء (الاستثناءات) التي تمت مواجهتها في عبارة try.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يتيح لك else أقسام التعليمات البرمجية التي يجب تشغيلها فقط عند عدم وجود استثناءات في جملة try.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يتيح لك أخيرًا تنفيذ أقسام التعليمات البرمجية التي يجب تشغيلها دائمًا ، مع أو بدون أي استثناءات تمت مواجهتها مسبقًا.<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">نأمل أن تساعدك هذه المقالة في فهم الأدوات الأساسية التي يجب أن تقدمها Python عند التعامل مع الاستثناءات.</span></p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d8%a7%d8%b3%d8%aa%d8%ab%d9%86%d8%a7%d8%a1%d8%a7%d8%aa-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-%d9%85%d9%82%d8%af%d9%85%d8%a9/">استثناءات بايثون: مقدمة</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://arabdars.com/%d8%a7%d8%b3%d8%aa%d8%ab%d9%86%d8%a7%d8%a1%d8%a7%d8%aa-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-%d9%85%d9%82%d8%af%d9%85%d8%a9/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>وحدة مسار بايثون 3: ترويض نظام الملفات</title>
		<link>https://arabdars.com/%d9%88%d8%ad%d8%af%d8%a9-%d9%85%d8%b3%d8%a7%d8%b1-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-3-%d8%aa%d8%b1%d9%88%d9%8a%d8%b6-%d9%86%d8%b8%d8%a7%d9%85-%d8%a7%d9%84%d9%85%d9%84%d9%81%d8%a7%d8%aa/</link>
					<comments>https://arabdars.com/%d9%88%d8%ad%d8%af%d8%a9-%d9%85%d8%b3%d8%a7%d8%b1-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-3-%d8%aa%d8%b1%d9%88%d9%8a%d8%b6-%d9%86%d8%b8%d8%a7%d9%85-%d8%a7%d9%84%d9%85%d9%84%d9%81%d8%a7%d8%aa/#respond</comments>
		
		<dc:creator><![CDATA[Reyhane]]></dc:creator>
		<pubDate>Mon, 21 Sep 2020 15:28:53 +0000</pubDate>
				<category><![CDATA[الماتلاب Matlab]]></category>
		<guid isPermaLink="false">https://arabdars.com/?p=1626</guid>

					<description><![CDATA[<p>جدول المحتويات مشكلة معالجة مسار ملف بايثون خلق المسارات قراءة وكتابة الملفات انتقاء مكونات المسار نقل وحذف الملفات أمثلة عد الملفات عرض شجرة الدليل ابحث عن آخر ملف تم تعديله قم بإنشاء اسم ملف فريد اختلافات نظام التشغيل المسارات ككائنات مناسبة خاتمة هل واجهت صعوبة في التعامل مع مسار الملف في بايثون؟ في Python 3.4 [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d9%88%d8%ad%d8%af%d8%a9-%d9%85%d8%b3%d8%a7%d8%b1-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-3-%d8%aa%d8%b1%d9%88%d9%8a%d8%b6-%d9%86%d8%b8%d8%a7%d9%85-%d8%a7%d9%84%d9%85%d9%84%d9%81%d8%a7%d8%aa/">وحدة مسار بايثون 3: ترويض نظام الملفات</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">جدول المحتويات</span></strong><br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">مشكلة معالجة مسار ملف بايثون<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">خلق المسارات<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">قراءة وكتابة الملفات<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">انتقاء مكونات المسار<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">نقل وحذف الملفات<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">أمثلة<br />
عد الملفات<br />
عرض شجرة الدليل<br />
ابحث عن آخر ملف تم تعديله<br />
قم بإنشاء اسم ملف فريد<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">اختلافات نظام التشغيل<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">المسارات ككائنات مناسبة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">خاتمة<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هل واجهت صعوبة في التعامل مع مسار الملف في بايثون؟ في Python 3.4 وما فوق ، انتهى الصراع الآن! لم تعد بحاجة إلى خدش رأسك فوق التعليمات البرمجية مثل:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">rsplit</span><span class="p">(</span><span class="s1">'</span><span class="se">\\</span><span class="s1">'</span><span class="p">,</span> <span class="n">maxsplit</span><span class="o">=</span><span class="mi">1</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">أو الاستياء من الإسهاب في:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isfile</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="s1">'~'</span><span class="p">),</span> <span class="s1">'realpython.txt'</span><span class="p">))</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في هذا البرنامج التعليمي ، سوف ترى كيفية التعامل مع مسارات الملفات &#8211; أسماء الأدلة والملفات &#8211; في Python. ستتعلم طرقًا جديدة لقراءة الملفات وكتابتها ، ومعالجة المسارات ونظام الملفات الأساسي ، بالإضافة إلى الاطلاع على بعض الأمثلة حول كيفية سرد الملفات وتكرارها. باستخدام وحدة pathlib ، يمكن إعادة كتابة المثالين أعلاه باستخدام رمز Pythonic أنيق وقابل للقراءة مثل:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">parent</span>
<span class="gp">&gt;&gt;&gt; </span><span class="p">(</span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">home</span><span class="p">()</span> <span class="o">/</span> <span class="s1">'realpython.txt'</span><span class="p">)</span><span class="o">.</span><span class="n">is_file</span><span class="p">()</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">مشكلة معالجة مسار ملف بايثون</span></strong></p>
<p>يعد العمل مع الملفات والتفاعل مع نظام الملفات أمرًا مهمًا لأسباب عديدة مختلفة. قد تتضمن أبسط الحالات قراءة الملفات أو كتابتها فقط ، ولكن في بعض الأحيان تكون المهام الأكثر تعقيدًا في متناول اليد. ربما تحتاج إلى سرد جميع الملفات في دليل من نوع معين ، أو العثور على الدليل الأصل لملف معين ، أو إنشاء اسم ملف فريد غير موجود بالفعل.</p>
<p>تقليديًا ، تمثل Python مسارات الملفات باستخدام سلاسل نصية عادية. بدعم من مكتبة os.path القياسية ، كان هذا مناسبًا على الرغم من كونه مرهقًا بعض الشيء (كما يوضح المثال الثاني في المقدمة). ومع ذلك ، نظرًا لأن المسارات ليست سلاسل ، تنتشر الوظائف المهمة في جميع أنحاء المكتبة القياسية ، بما في ذلك المكتبات مثل os و glob و shutil. يحتاج المثال التالي إلى ثلاث عبارات استيراد فقط لنقل جميع الملفات النصية إلى دليل أرشيف:<br />
</span></p>
<pre><code><span class="kn">import</span> <span class="nn">glob</span>
<span class="kn">import</span> <span class="nn">os</span>
<span class="kn">import</span> <span class="nn">shutil</span>

<span class="k">for</span> <span class="n">file_name</span> <span class="ow">in</span> <span class="n">glob</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s1">'*.txt'</span><span class="p">):</span>
    <span class="n">new_path</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="s1">'archive'</span><span class="p">,</span> <span class="n">file_name</span><span class="p">)</span>
    <span class="n">shutil</span><span class="o">.</span><span class="n">move</span><span class="p">(</span><span class="n">file_name</span><span class="p">,</span> <span class="n">new_path</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">مع المسارات التي يتم تمثيلها بواسطة سلاسل ، من الممكن ، ولكن عادة ما تكون فكرة سيئة ، استخدام طرق سلسلة منتظمة. على سبيل المثال ، بدلاً من ضم مسارين مع + مثل السلاسل العادية ، يجب عليك استخدام os.path.join () ، الذي يربط المسارات باستخدام فاصل المسار الصحيح في نظام التشغيل. تذكر أن Windows يستخدم \ بينما يستخدم Mac و Linux / كفاصل. يمكن أن يؤدي هذا الاختلاف إلى أخطاء يصعب تحديدها ، مثل مثالنا الأول في المقدمة الذي يعمل مع مسارات Windows فقط.</p>
<p>تم تقديم وحدة pathlib في Python 3.4 (PEP 428) للتعامل مع هذه التحديات. إنه يجمع الوظائف الضرورية في مكان واحد ويجعلها متاحة من خلال الأساليب والخصائص على كائن مسار سهل الاستخدام.</p>
<p>في وقت مبكر ، لا تزال الحزم الأخرى تستخدم سلاسل لمسارات الملفات ، ولكن اعتبارًا من Python 3.6 ، يتم دعم وحدة pathlib في جميع أنحاء المكتبة القياسية ، ويرجع ذلك جزئيًا إلى إضافة بروتوكول مسار نظام الملفات. إذا كنت عالقًا في Python القديمة ، فهناك أيضًا منفذ خلفي متاح لـ Python 2.</p>
<p>حان وقت العمل: دعونا نرى كيف يعمل pathlib عمليًا.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">خلق المسارات</span></strong></p>
<p>كل ما تحتاج إلى معرفته حقًا هو فئة pathlib.Path. هناك عدة طرق مختلفة لإنشاء المسار. أولاً وقبل كل شيء ، هناك طرق فصل مثل .cwd () (دليل العمل الحالي) و .home () (الدليل الرئيسي للمستخدم):<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">pathlib</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">cwd</span><span class="p">()</span>
<span class="go">PosixPath('/home/gahjelle/realpython/')</span>
</code></pre>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ملاحظة: خلال هذا البرنامج التعليمي ، سنفترض أن pathlib قد تم استيراده ، دون توضيح استيراد pathlib على النحو الوارد أعلاه. نظرًا لأنك ستستخدم فئة المسار بشكل أساسي ، يمكنك أيضًا القيام بذلك من pathlib import Path وكتابة Path بدلاً من pathlib.Path.<br />
</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن أيضًا إنشاء المسار بشكل صريح من تمثيل السلسلة الخاص به:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="sa">r</span><span class="s1">'C:\Users\gahjelle\realpython\file.txt'</span><span class="p">)</span>
<span class="go">WindowsPath('C:/Users/gahjelle/realpython/file.txt')</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">نصيحة صغيرة للتعامل مع مسارات Windows: في Windows ، يكون فاصل المسار عبارة عن شرطة مائلة للخلف ، \. ومع ذلك ، في العديد من السياقات ، تُستخدم الشرطة المائلة العكسية أيضًا كحرف هروب من أجل تمثيل الأحرف غير القابلة للطباعة. لتجنب المشاكل ، استخدم القيم الحرفية للسلسلة الأولية لتمثيل مسارات Windows. هذه عبارة عن سلسلة حرفية لها حرف r مُسبق لها. في سلسلة الأحرف الأولية ، يمثل \ خط مائل عكسي حرفي: r&#8217;C: \ Users &#8216;.</p>
<p>الطريقة الثالثة لبناء مسار هي الانضمام إلى أجزاء المسار باستخدام عامل التشغيل الخاص /. يتم استخدام عامل تشغيل الشرطة المائلة للأمام بشكل مستقل عن فاصل المسار الفعلي على المنصة:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">home</span><span class="p">()</span> <span class="o">/</span> <span class="s1">'python'</span> <span class="o">/</span> <span class="s1">'scripts'</span> <span class="o">/</span> <span class="s1">'test.py'</span>
<span class="go">PosixPath('/home/gahjelle/python/scripts/test.py')</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن أن يصل / إلى عدة مسارات أو مزيج من المسارات والسلاسل (على النحو الوارد أعلاه) طالما أن هناك كائن مسار واحد على الأقل. إذا لم تعجبك الخاص / الترميز ، يمكنك فعل الشيء نفسه باستخدام طريقة .joinpath ():<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">home</span><span class="p">()</span><span class="o">.</span><span class="n">joinpath</span><span class="p">(</span><span class="s1">'python'</span><span class="p">,</span> <span class="s1">'scripts'</span><span class="p">,</span> <span class="s1">'test.py'</span><span class="p">)</span>
<span class="go">PosixPath('/home/gahjelle/python/scripts/test.py')</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ أنه في الأمثلة السابقة ، يتم تمثيل pathlib.Path إما بواسطة WindowsPath أو PosixPath. يعتمد الكائن الفعلي الذي يمثل المسار على نظام التشغيل الأساسي. (بمعنى ، تم تشغيل مثال WindowsPath على نظام التشغيل Windows ، بينما تم تشغيل أمثلة PosixPath على نظام التشغيل Mac أو Linux.) راجع قسم &#8220;اختلافات نظام التشغيل&#8221; لمزيد من المعلومات.</p>
<p><strong><span style="font-size: 20pt">قراءة وكتابة الملفات</span></strong></span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تقليديًا ، كانت طريقة قراءة أو كتابة ملف في Python هي استخدام وظيفة open () المضمنة. لا يزال هذا صحيحًا لأن الوظيفة open () يمكنها استخدام كائنات المسار مباشرةً. يعثر المثال التالي على جميع الرؤوس في ملف Markdown ويطبعها:<br />
</span></p>
<pre><code><span class="n">path</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">cwd</span><span class="p">()</span> <span class="o">/</span> <span class="s1">'test.md'</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">mode</span><span class="o">=</span><span class="s1">'r'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fid</span><span class="p">:</span>
    <span class="n">headers</span> <span class="o">=</span> <span class="p">[</span><span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">fid</span> <span class="k">if</span> <span class="n">line</span><span class="o">.</span><span class="n">startswith</span><span class="p">(</span><span class="s1">'#'</span><span class="p">)]</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">headers</span><span class="p">))</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بديل مكافئ هو استدعاء .open () على كائن المسار:<br />
</span></p>
<pre><code><span class="k">with</span> <span class="n">path</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">mode</span><span class="o">=</span><span class="s1">'r'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fid</span><span class="p">:</span>
    <span class="o">...</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في الواقع ، يقوم Path.open () باستدعاء العنصر الداخلي open () خلف الكواليس. الخيار الذي تستخدمه هو في الأساس مسألة ذوق.</p>
<p>لقراءة الملفات وكتابتها بشكل بسيط ، هناك طريقتان ملائمتان في مكتبة pathlib:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">.</span><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">read_text (): افتح المسار في وضع النص وأعد المحتويات كسلسلة.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">.read_bytes (): افتح المسار في الوضع الثنائي / البايت وأعد المحتويات كاختبار بايت.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">.write_text (): افتح المسار واكتب بيانات السلسلة إليه.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">.write_bytes (): افتح المسار في الوضع الثنائي / بايت واكتب البيانات إليه.<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كل من هذه الطرق تتعامل مع فتح وإغلاق الملف ، مما يجعلها سهلة الاستخدام ، على سبيل المثال:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">path</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">cwd</span><span class="p">()</span> <span class="o">/</span> <span class="s1">'test.md'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">read_text</span><span class="p">()</span>
<span class="go">&lt;the contents of the test.md-file&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن أيضًا تحديد المسارات كأسماء ملفات بسيطة ، وفي هذه الحالة يتم تفسيرها بالنسبة إلى دليل العمل الحالي. المثال التالي يعادل المثال السابق:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="s1">'test.md'</span><span class="p">)</span><span class="o">.</span><span class="n">read_text</span><span class="p">()</span>
<span class="go">&lt;the contents of the test.md-file&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">سيجد الأسلوب .resolve () المسار الكامل. أدناه ، نؤكد أن دليل العمل الحالي يُستخدم لأسماء الملفات البسيطة:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">path</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="s1">'test.md'</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">resolve</span><span class="p">()</span>
<span class="go">PosixPath('/home/gahjelle/realpython/test.md')</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">resolve</span><span class="p">()</span><span class="o">.</span><span class="n">parent</span> <span class="o">==</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">cwd</span><span class="p">()</span>
<span class="go">True</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">parent</span> <span class="o">==</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">cwd</span><span class="p">()</span>
<span class="go">False</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ أنه عند مقارنة المسارات ، يتم مقارنة تمثيلاتها. في المثال أعلاه ، path.parent لا يساوي pathlib.Path.cwd () ، لأن path.parent يتم تمثيله بواسطة &#8220;.&#8221; بينما يتم تمثيل pathlib.Path.cwd () بـ &#8220;/ home / gahjelle / realpython /&#8221;.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">انتقاء مكونات المسار</span></strong></p>
<p>الأجزاء المختلفة من المسار متوفرة بسهولة كخصائص. تشمل الأمثلة الأساسية ما يلي:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">.name: اسم الملف بدون أي دليل<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">.parent: الدليل الذي يحتوي على الملف ، أو الدليل الأصل إذا كان المسار عبارة عن دليل<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">.stem: اسم الملف بدون اللاحقة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">.suffix: امتداد الملف<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">.anchor: جزء المسار قبل الدلائل<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">فيما يلي هذه الخصائص قيد التشغيل:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">path</span>
<span class="go">PosixPath('/home/gahjelle/realpython/test.md')</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">name</span>
<span class="go">'test.md'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">stem</span>
<span class="go">'test'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">suffix</span>
<span class="go">'.md'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">parent</span>
<span class="go">PosixPath('/home/gahjelle/realpython')</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">parent</span>
<span class="go">PosixPath('/home/gahjelle')</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">anchor</span>
<span class="go">'/'</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ أن .parent ترجع كائن مسار جديد ، بينما تقوم الخصائص الأخرى بإرجاع سلاسل. هذا يعني على سبيل المثال أنه يمكن ربط .parent كما في المثال الأخير أو حتى دمجها مع / لإنشاء مسارات جديدة تمامًا:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">parent</span><span class="o">.</span><span class="n">parent</span> <span class="o">/</span> <span class="p">(</span><span class="s1">'new'</span> <span class="o">+</span> <span class="n">path</span><span class="o">.</span><span class="n">suffix</span><span class="p">)</span>
<span class="go">PosixPath('/home/gahjelle/new.md')</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">توفر ورقة غش Pathlib الممتازة تمثيلًا مرئيًا لهذه الخصائص والطرق وغيرها.</p>
<p><strong><span style="font-size: 20pt">نقل وحذف الملفات</span></strong></p>
<p>من خلال pathlib ، يمكنك أيضًا الوصول إلى عمليات مستوى نظام الملفات الأساسية مثل نقل الملفات وتحديثها وحتى حذفها. بالنسبة للجزء الأكبر ، لا تعطي هذه الطرق تحذيرًا أو تنتظر التأكيد قبل فقد المعلومات أو الملفات. كن حذرا عند استخدام هذه الأساليب.</p>
<p>لنقل ملف ، استخدم .replace (). لاحظ أنه إذا كانت الوجهة موجودة بالفعل ، فسيحل محلها .replace (). لسوء الحظ ، لا يدعم pathlib صراحة النقل الآمن للملفات. لتجنب احتمال الكتابة فوق مسار الوجهة ، فإن أبسط شيء هو اختبار ما إذا كانت الوجهة موجودة قبل استبدال:<br />
</span></p>
<pre><code><span class="k">if</span> <span class="ow">not</span> <span class="n">destination</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
    <span class="n">source</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">destination</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ومع ذلك ، فإن هذا يترك الباب مفتوحًا لظروف السباق المحتملة. قد تضيف عملية أخرى ملفًا في مسار الوجهة بين تنفيذ تعليمة if وطريقة .replace (). إذا كان هذا مصدر قلق ، فإن الطريقة الأكثر أمانًا هي فتح مسار الوجهة لإنشاء حصري ونسخ بيانات المصدر بشكل صريح:<br />
</span></p>
<pre><code><span class="k">with</span> <span class="n">destination</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">mode</span><span class="o">=</span><span class="s1">'xb'</span><span class="p">)</span> <span class="k">as</span> <span class="n">fid</span><span class="p">:</span>
    <span class="n">fid</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">source</span><span class="o">.</span><span class="n">read_bytes</span><span class="p">())</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">سيؤدي الكود أعلاه إلى رفع FileExistsError إذا كانت الوجهة موجودة بالفعل. من الناحية الفنية ، هذا ينسخ ملفًا. لإجراء نقل ، ما عليك سوى حذف المصدر بعد الانتهاء من النسخ (انظر أدناه). تأكد من عدم وجود استثناء على الرغم من.</p>
<p>عندما تعيد تسمية الملفات ، قد تكون الطرق المفيدة .with_name () و .with_suffix (). كلاهما يعيد المسار الأصلي ولكن مع استبدال الاسم أو اللاحقة ، على التوالي.</p>
<p>على سبيل المثال:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">path</span>
<span class="go">PosixPath('/home/gahjelle/realpython/test001.txt')</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">with_suffix</span><span class="p">(</span><span class="s1">'.py'</span><span class="p">)</span>
<span class="go">PosixPath('/home/gahjelle/realpython/test001.py')</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">with_suffix</span><span class="p">(</span><span class="s1">'.py'</span><span class="p">))</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن حذف الدلائل والملفات باستخدام .rmdir () و .unlink () على التوالي. (مرة أخرى ، كن حذرا!)<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">أمثلة</span></strong></p>
<p>في هذا القسم ، سترى بعض الأمثلة على كيفية استخدام pathlib للتعامل مع التحديات البسيطة.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>عد الملفات</strong></p>
<p>هناك عدة طرق مختلفة لسرد العديد من الملفات. أبسطها هي طريقة .iterdir () ، والتي تتكرر عبر جميع الملفات في الدليل المحدد. يجمع المثال التالي بين .iterdir () والمجموعات. فئة Counter لحساب عدد الملفات الموجودة لكل نوع ملف في الدليل الحالي:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">collections</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">collections</span><span class="o">.</span><span class="n">Counter</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">suffix</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">cwd</span><span class="p">()</span><span class="o">.</span><span class="n">iterdir</span><span class="p">())</span>
<span class="go">Counter({'.md': 2, '.txt': 4, '.pdf': 2, '.py': 1})</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن إنشاء قوائم ملفات أكثر مرونة باستخدام الأساليب .glob () و .rglob () (الكرة العودية العودية). على سبيل المثال ، يقوم pathlib.Path.cwd (). glob (&#8216;*. txt&#8217;) بإرجاع جميع الملفات التي تحتوي على لاحقة .txt في الدليل الحالي. فيما يلي فقط أنواع الملفات التي تبدأ بـ p:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">collections</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">collections</span><span class="o">.</span><span class="n">Counter</span><span class="p">(</span><span class="n">p</span><span class="o">.</span><span class="n">suffix</span> <span class="k">for</span> <span class="n">p</span> <span class="ow">in</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">cwd</span><span class="p">()</span><span class="o">.</span><span class="n">glob</span><span class="p">(</span><span class="s1">'*.p*'</span><span class="p">))</span>
<span class="go">Counter({'.pdf': 2, '.py': 1})</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>عرض شجرة الدليل</strong></p>
<p>يحدد المثال التالي دالة ، الشجرة () ، والتي ستطبع شجرة مرئية تمثل التسلسل الهرمي للملف ، متجذرة في دليل معين. هنا ، نريد سرد الأدلة الفرعية أيضًا ، لذلك نستخدم طريقة .rglob ():</span></p>
<pre><code><span class="k">def</span> <span class="nf">tree</span><span class="p">(</span><span class="n">directory</span><span class="p">):</span>
    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'+ </span><span class="si">{</span><span class="n">directory</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">directory</span><span class="o">.</span><span class="n">rglob</span><span class="p">(</span><span class="s1">'*'</span><span class="p">)):</span>
        <span class="n">depth</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">path</span><span class="o">.</span><span class="n">relative_to</span><span class="p">(</span><span class="n">directory</span><span class="p">)</span><span class="o">.</span><span class="n">parts</span><span class="p">)</span>
        <span class="n">spacer</span> <span class="o">=</span> <span class="s1">'    '</span> <span class="o">*</span> <span class="n">depth</span>
        <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'</span><span class="si">{</span><span class="n">spacer</span><span class="si">}</span><span class="s1">+ </span><span class="si">{</span><span class="n">path</span><span class="o">.</span><span class="n">name</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ أننا نحتاج إلى معرفة المسافة البُعدية التي يقع فيها الملف عن الدليل الجذر. للقيام بذلك ، نستخدم أولاً .relative_to () لتمثيل مسار متعلق بالدليل الجذر. بعد ذلك ، نحسب عدد الأدلة (باستخدام خاصية .parts) في التمثيل. عند التشغيل ، تنشئ هذه الوظيفة شجرة مرئية مثل ما يلي:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">tree</span><span class="p">(</span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">cwd</span><span class="p">())</span>
<span class="go">+ /home/gahjelle/realpython</span>
<span class="go">    + directory_1</span>
<span class="go">        + file_a.md</span>
<span class="go">    + directory_2</span>
<span class="go">        + file_a.md</span>
<span class="go">        + file_b.pdf</span>
<span class="go">        + file_c.py</span>
<span class="go">    + file_1.txt</span>
<span class="go">    + file_2.txt</span>
</code></pre>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ملاحظة: لا تعمل سلاسل f إلا في Python 3.6 والإصدارات الأحدث. في لغة Pythons الأقدم ، يمكن كتابة التعبير f &#8216;{spacer} + {path.name}&#8217; {0} + {1} &#8216;. (spacer، path.name).<br />
</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>ابحث عن آخر ملف تم تعديله</strong></p>
<p>تعتبر طرق .iterdir () و .glob () و .rglob () مناسبة جدًا لتعبيرات المولد وفهم القوائم. للعثور على الملف في دليل تم تعديله مؤخرًا ، يمكنك استخدام طريقة .stat () للحصول على معلومات حول الملفات الأساسية. على سبيل المثال ، يعطي .stat (). st_mtime وقت آخر تعديل لملف:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">time</span><span class="p">,</span> <span class="n">file_path</span> <span class="o">=</span> <span class="nb">max</span><span class="p">((</span><span class="n">f</span><span class="o">.</span><span class="n">stat</span><span class="p">()</span><span class="o">.</span><span class="n">st_mtime</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">directory</span><span class="o">.</span><span class="n">iterdir</span><span class="p">())</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">time</span><span class="p">),</span> <span class="n">file_path</span><span class="p">)</span>
<span class="go">2018-03-23 19:23:56.977817 /home/gahjelle/realpython/test001.txt</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكنك حتى الحصول على محتويات الملف الذي تم تعديله آخر مرة بتعبير مشابه:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">max</span><span class="p">((</span><span class="n">f</span><span class="o">.</span><span class="n">stat</span><span class="p">()</span><span class="o">.</span><span class="n">st_mtime</span><span class="p">,</span> <span class="n">f</span><span class="p">)</span> <span class="k">for</span> <span class="n">f</span> <span class="ow">in</span> <span class="n">directory</span><span class="o">.</span><span class="n">iterdir</span><span class="p">())[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">read_text</span><span class="p">()</span>
<span class="go">&lt;the contents of the last modified file in directory&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمثل الطابع الزمني الذي تم إرجاعه من خصائص .stat (). st_ المختلفة الثواني منذ الأول من يناير 1970. بالإضافة إلى datetime.fromtimestamp ، يمكن استخدام time.localtime أو time.ctime لتحويل الطابع الزمني إلى شيء أكثر قابلية للاستخدام.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>قم بإنشاء اسم ملف فريد</strong></p>
<p>سيوضح المثال الأخير كيفية إنشاء اسم ملف مرقم فريد بناءً على قالب. أولاً ، حدد نمطًا لاسم الملف ، مع مساحة للعداد. بعد ذلك ، تحقق من وجود مسار الملف الذي تم إنشاؤه من خلال الانضمام إلى دليل واسم الملف (مع قيمة للعداد). إذا كان موجودًا بالفعل ، فقم بزيادة العداد وحاول مرة أخرى:<br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">unique_path</span><span class="p">(</span><span class="n">directory</span><span class="p">,</span> <span class="n">name_pattern</span><span class="p">):</span>
    <span class="n">counter</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
        <span class="n">counter</span> <span class="o">+=</span> <span class="mi">1</span>
        <span class="n">path</span> <span class="o">=</span> <span class="n">directory</span> <span class="o">/</span> <span class="n">name_pattern</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">counter</span><span class="p">)</span>
        <span class="k">if</span> <span class="ow">not</span> <span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">():</span>
            <span class="k">return</span> <span class="n">path</span>

<span class="n">path</span> <span class="o">=</span> <span class="n">unique_path</span><span class="p">(</span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="o">.</span><span class="n">cwd</span><span class="p">(),</span> <span class="s1">'test</span><span class="si">{:03d}</span><span class="s1">.txt'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا كان الدليل يحتوي بالفعل على الملفين test001.txt و test002.txt ، فسيقوم الرمز أعلاه بتعيين المسار إلى test003.txt.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">اختلافات نظام التشغيل</span></strong></p>
<p>لاحظنا سابقًا أنه عندما قمنا بإنشاء مثيل لـ pathlib.Path ، تم إرجاع كائن WindowsPath أو PosixPath. يعتمد نوع الكائن على نظام التشغيل الذي تستخدمه. هذه الميزة تجعل من السهل إلى حد ما كتابة رمز متوافق عبر الأنظمة الأساسية. من الممكن أن تطلب WindowsPath أو PosixPath صراحة ، لكنك ستقتصر رمزك على هذا النظام فقط دون أي فوائد. لا يمكن استخدام مسار ملموس مثل هذا في نظام مختلف:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">pathlib</span><span class="o">.</span><span class="n">WindowsPath</span><span class="p">(</span><span class="s1">'test.md'</span><span class="p">)</span>
<span class="go">NotImplementedError: cannot instantiate 'WindowsPath' on your system</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">قد تكون هناك أوقات تحتاج فيها إلى تمثيل المسار دون الوصول إلى نظام الملفات الأساسي (في هذه الحالة قد يكون من المنطقي أيضًا تمثيل مسار Windows على نظام بخلاف Windows أو العكس). يمكن القيام بذلك باستخدام كائنات PurePath. تدعم هذه الكائنات العمليات التي تمت مناقشتها في القسم الخاص بمكونات المسار ولكن ليس الطرق التي تصل إلى نظام الملفات:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">path</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">PureWindowsPath</span><span class="p">(</span><span class="sa">r</span><span class="s1">'C:\Users\gahjelle\realpython\file.txt'</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">name</span>
<span class="go">'file.txt'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">parent</span>
<span class="go">PureWindowsPath('C:/Users/gahjelle/realpython')</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span><span class="o">.</span><span class="n">exists</span><span class="p">()</span>
<span class="go">AttributeError: 'PureWindowsPath' object has no attribute 'exists'</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكنك إنشاء مثيل PureWindowsPath أو PurePosixPath مباشرة على جميع الأنظمة. سيؤدي Instantiating PurePath إلى إرجاع أحد هذه الكائنات اعتمادًا على نظام التشغيل الذي تستخدمه.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">المسارات ككائنات مناسبة</span></strong></p>
<p>في المقدمة ، لاحظنا بإيجاز أن المسارات ليست سلاسل ، والدافع وراء pathlib هو تمثيل نظام الملفات بالكائنات المناسبة. في الواقع ، التوثيق الرسمي لـ pathlib هو pathlib &#8211; مسارات نظام الملفات الموجهة للكائنات. إن النهج الموجه للكائنات مرئي بالفعل في الأمثلة أعلاه (خاصة إذا كنت تتناقض مع طريقة os.path القديمة للقيام بالأشياء). ومع ذلك ، دعني أترك لك بعض الحكايات الأخرى.</p>
<p>بصرف النظر عن نظام التشغيل الذي تستخدمه ، يتم تمثيل المسارات بأسلوب Posix ، مع استخدام الشرطة المائلة للأمام كفاصل للمسار. في Windows ، سترى شيئًا كهذا:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="sa">r</span><span class="s1">'C:\Users\gahjelle\realpython\file.txt'</span><span class="p">)</span>
<span class="go">WindowsPath('C:/Users/gahjelle/realpython/file.txt')</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ومع ذلك ، عندما يتم تحويل مسار إلى سلسلة ، فإنه سيستخدم النموذج الأصلي ، على سبيل المثال مع خطوط مائلة عكسية على Windows:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span><span class="p">(</span><span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="sa">r</span><span class="s1">'C:\Users\gahjelle\realpython\file.txt'</span><span class="p">))</span>
<span class="go">'C:\\Users\\gahjelle\\realpython\\file.txt'</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هذا مفيد بشكل خاص إذا كنت تستخدم مكتبة لا تعرف كيفية التعامل مع كائنات pathlib.Path. هذه مشكلة أكبر في إصدارات Python قبل 3.6. على سبيل المثال ، في Python 3.5 ، يمكن لمكتبة configparser القياسية استخدام مسارات سلسلة فقط لقراءة الملفات. طريقة معالجة مثل هذه الحالات هي القيام بالتحويل إلى سلسلة بشكل صريح:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">configparser</span> <span class="kn">import</span> <span class="n">ConfigParser</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">path</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="s1">'config.txt'</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">cfg</span> <span class="o">=</span> <span class="n">ConfigParser</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">cfg</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="n">path</span><span class="p">)</span>                     <span class="c1"># Error on Python &lt; 3.6</span>
<span class="go">TypeError: 'PosixPath' object is not iterable</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">cfg</span><span class="o">.</span><span class="n">read</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>                <span class="c1"># Works on Python &gt;= 3.4</span>
<span class="go">['config.txt']</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في Python 3.6 والإصدارات الأحدث ، يوصى باستخدام os.fspath () بدلاً من str () إذا كنت بحاجة إلى إجراء تحويل صريح. يعد هذا أكثر أمانًا لأنه سيؤدي إلى حدوث خطأ إذا حاولت عن طريق الخطأ تحويل كائن لا يشبه المسار.</p>
<p>من المحتمل أن يكون الجزء الأكثر غرابة من مكتبة pathlib هو استخدام العامل /. لإلقاء نظرة خاطفة على الغطاء ، دعونا نرى كيف يتم تنفيذ ذلك. هذا مثال على التحميل الزائد للمشغل: يتغير سلوك المشغل حسب السياق. لقد رأيت هذا من قبل. فكر في كيف + تعني أشياء مختلفة للسلاسل والأرقام. تنفذ Python التحميل الزائد للمشغل من خلال استخدام أساليب الشرطة السفلية المزدوجة (المعروفة أيضًا بأساليب dunder).</p>
<p>يتم تحديد عامل التشغيل / بواسطة طريقة .__ truediv __ (). في الواقع ، إذا ألقيت نظرة على الكود المصدري لـ pathlib ، فسترى شيئًا مثل:<br />
</span></p>
<pre><code><span class="k">class</span> <span class="nc">PurePath</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>

    <span class="k">def</span> <span class="fm">__truediv__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_make_child</span><span class="p">((</span><span class="n">key</span><span class="p">,))</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">خاتمة</span></strong></p>
<p>منذ Python 3.4 ، أصبح pathlib متاحًا في المكتبة القياسية. باستخدام pathlib ، يمكن تمثيل مسارات الملفات بواسطة كائنات المسار المناسبة بدلاً من السلاسل العادية كما في السابق. هذه الكائنات تجعل التعليمات البرمجية تتعامل مع مسارات الملفات:</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span title="">أسهل للقراءة ، خاصةً لأنه / يُستخدم لربط المسارات معًا</span><br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span title="">أكثر قوة ، مع توفر معظم الأساليب والخصائص الضرورية مباشرة على الكائن</span><br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span title="">أكثر اتساقًا عبر أنظمة التشغيل ، حيث يتم إخفاء خصائص الأنظمة المختلفة بواسطة كائن المسار</span><br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span class="" title="">في هذا البرنامج التعليمي ، رأيت كيفية إنشاء كائنات المسار ، وقراءة الملفات وكتابتها ، ومعالجة المسارات ونظام الملفات الأساسي ، بالإضافة إلى بعض الأمثلة عن كيفية التكرار عبر العديد من مسارات الملفات.</span></span></p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d9%88%d8%ad%d8%af%d8%a9-%d9%85%d8%b3%d8%a7%d8%b1-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-3-%d8%aa%d8%b1%d9%88%d9%8a%d8%b6-%d9%86%d8%b8%d8%a7%d9%85-%d8%a7%d9%84%d9%85%d9%84%d9%81%d8%a7%d8%aa/">وحدة مسار بايثون 3: ترويض نظام الملفات</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://arabdars.com/%d9%88%d8%ad%d8%af%d8%a9-%d9%85%d8%b3%d8%a7%d8%b1-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-3-%d8%aa%d8%b1%d9%88%d9%8a%d8%b6-%d9%86%d8%b8%d8%a7%d9%85-%d8%a7%d9%84%d9%85%d9%84%d9%81%d8%a7%d8%aa/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>وحدات وحزم بايثون &#8211; مقدمة</title>
		<link>https://arabdars.com/%d9%88%d8%ad%d8%af%d8%a7%d8%aa-%d9%88%d8%ad%d8%b2%d9%85-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-%d9%85%d9%82%d8%af%d9%85%d8%a9/</link>
					<comments>https://arabdars.com/%d9%88%d8%ad%d8%af%d8%a7%d8%aa-%d9%88%d8%ad%d8%b2%d9%85-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-%d9%85%d9%82%d8%af%d9%85%d8%a9/#respond</comments>
		
		<dc:creator><![CDATA[Reyhane]]></dc:creator>
		<pubDate>Mon, 21 Sep 2020 14:11:43 +0000</pubDate>
				<category><![CDATA[الماتلاب Matlab]]></category>
		<guid isPermaLink="false">https://arabdars.com/?p=1624</guid>

					<description><![CDATA[<p>جدول المحتويات وحدات بايثون: نظرة عامة مسار بحث الوحدة النمطية بيان الاستيراد استيراد &#60;module_name&#62; من &#60;module_name&#62; استيراد &#60;الاسم (الأسماء)&#62; من &#60;module_name&#62; استيراد &#60;name&#62; كـ &#60;alt_name&#62; استيراد &#60;module_name&#62; كـ &#60;alt_name&#62; دالة دير () تنفيذ وحدة كبرنامج نصي إعادة تحميل وحدة حزم بايثون تهيئة الحزمة استيراد * من حزمة الحزم الفرعية خاتمة تستكشف هذه المقالة وحدات Python [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d9%88%d8%ad%d8%af%d8%a7%d8%aa-%d9%88%d8%ad%d8%b2%d9%85-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-%d9%85%d9%82%d8%af%d9%85%d8%a9/">وحدات وحزم بايثون &#8211; مقدمة</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">جدول المحتويات</span></strong></p>
<p></span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">وحدات بايثون: نظرة عامة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">مسار بحث الوحدة النمطية<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بيان الاستيراد<br />
استيراد &lt;module_name&gt;<br />
من &lt;module_name&gt; استيراد &lt;الاسم (الأسماء)&gt;<br />
من &lt;module_name&gt; استيراد &lt;name&gt; كـ &lt;alt_name&gt;<br />
استيراد &lt;module_name&gt; كـ &lt;alt_name&gt;<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">دالة دير ()<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تنفيذ وحدة كبرنامج نصي<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إعادة تحميل وحدة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">حزم بايثون<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تهيئة الحزمة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">استيراد * من حزمة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الحزم الفرعية<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">خاتمة<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تستكشف هذه المقالة وحدات Python وحزم Python ، وهما آليتان تسهّلان البرمجة المعيارية.</p>
<p>تشير البرمجة المعيارية إلى عملية تقسيم مهمة برمجة كبيرة غير عملية إلى مهام فرعية أو وحدات منفصلة وأصغر وأكثر قابلية للإدارة. يمكن بعد ذلك تجميع الوحدات الفردية معًا مثل اللبنات الأساسية لإنشاء تطبيق أكبر.</p>
<p>هناك العديد من المزايا لوحدة الكود في تطبيق كبير:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>البساطة:</strong> بدلاً من التركيز على المشكلة بأكملها ، تركز الوحدة عادةً على جزء صغير نسبيًا من المشكلة. إذا كنت تعمل على وحدة واحدة ، فسيكون لديك نطاق مشكلة أصغر للالتفاف حوله. هذا يجعل التطوير أسهل وأقل عرضة للخطأ.
<p></span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>قابلية الصيانة:</strong> يتم تصميم الوحدات النمطية عادةً بحيث تفرض الحدود المنطقية بين مجالات المشكلة المختلفة. إذا تمت كتابة الوحدات بطريقة تقلل من الاعتماد المتبادل ، فهناك احتمال أقل بأن التعديلات على وحدة واحدة سيكون لها تأثير على أجزاء أخرى من البرنامج. (قد تكون قادرًا على إجراء تغييرات على وحدة نمطية دون أن يكون لديك أي معرفة بالتطبيق خارج تلك الوحدة.) وهذا يجعل الأمر أكثر قابلية للتطبيق لفريق من المبرمجين للعمل بشكل تعاوني على تطبيق كبير.
<p></span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>قابلية إعادة الاستخدام:</strong> يمكن إعادة استخدام الوظيفة المحددة في وحدة واحدة بسهولة (من خلال واجهة محددة بشكل مناسب) بواسطة أجزاء أخرى من التطبيق. هذا يلغي الحاجة إلى تكرار التعليمات البرمجية.
<p></span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>تحديد النطاق:</strong> تحدد الوحدات عادةً مساحة اسم منفصلة ، مما يساعد على تجنب الاصطدامات بين المعرفات في مناطق مختلفة من البرنامج. (أحد المبادئ في Zen of Python هو أن Namespaces هي فكرة رائعة &#8211; فلنفعل المزيد منها!)<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الوظائف والوحدات والحزم كلها بنيات في بايثون تعزز تشكيل الكود.</p>
<p><strong><span style="font-size: 20pt">وحدات بايثون: نظرة عامة</span></strong></p>
<p>توجد في الواقع ثلاث طرق مختلفة لتعريف وحدة في بايثون:<br />
</span></p>
<ol>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن كتابة الوحدة في بايثون نفسها.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن كتابة وحدة في C وتحميلها ديناميكيًا في وقت التشغيل ، مثل وحدة re (التعبير العادي).<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">توجد وحدة مضمنة بشكل جوهري في المترجم الفوري ، مثل وحدة itertools.<br />
</span></li>
</ol>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يتم الوصول إلى محتويات الوحدة بنفس الطريقة في جميع الحالات الثلاث: مع بيان الاستيراد.</p>
<p>هنا ، سيكون التركيز في الغالب على الوحدات المكتوبة بلغة بايثون. إن الشيء الرائع في الوحدات المكتوبة بلغة بايثون هو أنها سهلة البناء للغاية. كل ما عليك فعله هو إنشاء ملف يحتوي على كود Python شرعي ثم إعطاء الملف اسمًا بامتداد .py. هذا هو! ليس هناك حاجة إلى صياغة خاصة أو الفودو.</p>
<p>على سبيل المثال ، افترض أنك قمت بإنشاء ملف يسمى mod.py يحتوي على ما يلي:</p>
<p><strong>mod.py</strong><br />
</span></p>
<pre><code><span class="n">s</span> <span class="o">=</span> <span class="s2">"If Comrade Napoleon says it, it must be right."</span>
<span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">100</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">300</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'arg = </span><span class="si">{</span><span class="n">arg</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
    <span class="k">pass</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يتم تحديد عدة كائنات في mod.py:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ق (سلسلة)<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">أ (قائمة)<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">foo</span><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"> () (دالة)<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">Foo (فصل دراسي)<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بافتراض وجود mod.py في موقع مناسب ، ستتعلم المزيد عنه قريبًا ، يمكن الوصول إلى هذه الكائنات عن طريق استيراد الوحدة على النحو التالي:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="n">mod</span><span class="o">.</span><span class="n">s</span><span class="p">)</span>
<span class="go">If Comrade Napoleon says it, it must be right.</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod</span><span class="o">.</span><span class="n">a</span>
<span class="go">[100, 200, 300]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod</span><span class="o">.</span><span class="n">foo</span><span class="p">([</span><span class="s1">'quux'</span><span class="p">,</span> <span class="s1">'corge'</span><span class="p">,</span> <span class="s1">'grault'</span><span class="p">])</span>
<span class="go">arg = ['quux', 'corge', 'grault']</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">mod</span><span class="o">.</span><span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span>
<span class="go">&lt;mod.Foo object at 0x03C181F0&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">مسار بحث الوحدة النمطية</span></strong></p>
<p>متابعة للمثال أعلاه ، دعنا نلقي نظرة على ما يحدث عندما تنفذ بايثون العبارة:<br />
</span></p>
<pre><code><span class="kn">import</span> <span class="nn">mod</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عندما ينفذ المترجم بيان الاستيراد أعلاه ، فإنه يبحث عن mod.py في قائمة الأدلة المجمعة من المصادر التالية:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الدليل الذي تم تشغيل نص الإدخال منه أو الدليل الحالي إذا كان المترجم يعمل بشكل تفاعلي<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">قائمة الدلائل الموجودة في متغير بيئة PYTHONPATH ، إذا تم تعيينها. (يعتمد تنسيق PYTHONPATH على نظام التشغيل ولكن يجب أن يحاكي متغير بيئة PATH.)<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">قائمة أدلة تعتمد على التثبيت تم تكوينها في وقت تثبيت Python<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن الوصول إلى مسار البحث الناتج في متغير Python sys.path ، والذي يتم الحصول عليه من وحدة نمطية تسمى sys:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">path</span>
<span class="go">['', 'C:\\Users\\john\\Documents\\Python\\doc', 'C:\\Python36\\Lib\\idlelib',</span>
<span class="go">'C:\\Python36\\python36.zip', 'C:\\Python36\\DLLs', 'C:\\Python36\\lib',</span>
<span class="go">'C:\\Python36', 'C:\\Python36\\lib\\site-packages']</span>
</code></pre>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ملاحظة: تعتمد المحتويات الدقيقة لـ sys.path على التثبيت. من شبه المؤكد أن ما سبق سيبدو مختلفًا قليلاً على جهاز الكمبيوتر الخاص بك.<br />
</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">وبالتالي ، للتأكد من العثور على الوحدة النمطية الخاصة بك ، عليك القيام بأحد الإجراءات التالية:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ضع mod.py في الدليل حيث يوجد نص الإدخال أو الدليل الحالي ، إذا كان تفاعليًا<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">قم بتعديل متغير بيئة PYTHONPATH ليحتوي على الدليل حيث يوجد mod.py قبل بدء تشغيل المترجم<br />
أو: ضع mod.py في أحد المجلدات الموجودة بالفعل في متغير PYTHONPATH<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ضع mod.py في أحد الأدلة المعتمدة على التثبيت ، والتي قد يكون لديك حق الوصول للكتابة إليها أو لا ، اعتمادًا على نظام التشغيل</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يوجد بالفعل خيار إضافي واحد: يمكنك وضع ملف الوحدة النمطية في أي دليل من اختيارك ثم تعديل sys.path في وقت التشغيل بحيث يحتوي على هذا الدليل. على سبيل المثال ، في هذه الحالة ، يمكنك وضع mod.py في الدليل C: \ Users \ john ثم إصدار العبارات التالية:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">r</span><span class="s1">'C:\Users\john'</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">path</span>
<span class="go">['', 'C:\\Users\\john\\Documents\\Python\\doc', 'C:\\Python36\\Lib\\idlelib',</span>
<span class="go">'C:\\Python36\\python36.zip', 'C:\\Python36\\DLLs', 'C:\\Python36\\lib',</span>
<span class="go">'C:\\Python36', 'C:\\Python36\\lib\\site-packages', 'C:\\Users\\john']</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بمجرد استيراد الوحدة ، يمكنك تحديد الموقع الذي تم العثور عليها فيه باستخدام سمة __ملف__ للوحدة:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod</span><span class="o">.</span><span class="vm">__file__</span>
<span class="go">'C:\\Users\\john\\mod.py'</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">re</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">re</span><span class="o">.</span><span class="vm">__file__</span>
<span class="go">'C:\\Python36\\lib\\re.py'</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يجب أن يكون جزء الدليل من __file__ أحد الأدلة في sys.path.</p>
<p><strong><span style="font-size: 20pt">بيان الاستيراد</span></strong></p>
<p>يتم توفير محتويات الوحدة للمتصل مع بيان الاستيراد. يأخذ بيان الاستيراد عدة أشكال مختلفة ، كما هو موضح أدناه.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>استيراد &lt;module_name&gt;</strong></p>
<p>أبسط شكل هو الذي سبق عرضه أعلاه:<br />
</span></p>
<pre><code><span class="kn">import</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ أن هذا لا يجعل محتويات الوحدة قابلة للوصول مباشرة إلى المتصل. تحتوي كل وحدة نمطية على جدول الرموز الخاص بها ، والذي يعمل كجدول الرموز العام لجميع الكائنات المحددة في الوحدة النمطية. وبالتالي ، فإن الوحدة النمطية تنشئ مساحة اسم منفصلة ، كما لوحظ بالفعل.</p>
<p>العبارة import &lt;module_name&gt; تضع فقط &lt;module_name&gt; في جدول رموز المتصل. تظل الكائنات المحددة في الوحدة النمطية في جدول الرموز الخاص بالوحدة النمطية.</p>
<p>من المتصل ، يمكن الوصول إلى الكائنات الموجودة في الوحدة فقط عندما تكون مسبوقة بـ &lt;module_name&gt; عبر تدوين النقطة ، كما هو موضح أدناه.</p>
<p>بعد بيان الاستيراد التالي ، يتم وضع mod في جدول الرموز المحلي. وبالتالي ، فإن mod لها معنى في السياق المحلي للمتصل:</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod</span>
<span class="go">&lt;module 'mod' from 'C:\\Users\\john\\Documents\\Python\\doc\\mod.py'&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ولكن تظل s و foo في جدول الرموز الخاص بالوحدة وليست لها مغزى في السياق المحلي:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">s</span>
<span class="go">NameError: name 's' is not defined</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foo</span><span class="p">(</span><span class="s1">'quux'</span><span class="p">)</span>
<span class="go">NameError: name 'foo' is not defined</span></code><code>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ليتم الوصول إليها في السياق المحلي ، يجب أن تكون أسماء الكائنات المحددة في الوحدة مسبوقة بـ mod:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">mod</span><span class="o">.</span><span class="n">s</span>
<span class="go">'If Comrade Napoleon says it, it must be right.'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod</span><span class="o">.</span><span class="n">foo</span><span class="p">(</span><span class="s1">'quux'</span><span class="p">)</span>
<span class="go">arg = quux</span></code><code>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن تحديد عدة وحدات مفصولة بفواصل في بيان استيراد واحد:</span></p>
<p><code><span class="kn">import</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span><span class="p">[,</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span> <span class="o">...</span><span class="p">]</span></code><code></code></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>من &lt;module_name&gt; استيراد &lt;الاسم (الأسماء)&gt;</strong></p>
<p>يسمح الشكل البديل لبيان الاستيراد باستيراد العناصر الفردية من الوحدة مباشرة إلى جدول رموز المتصل:<br />
</span></p>
<pre><code><span class="kn">from</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span> <span class="kn">import</span> <span class="o">&lt;</span><span class="n">name</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="o">&gt;</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بعد تنفيذ العبارة أعلاه ، يمكن الإشارة إلى &lt;name (s)&gt; في بيئة المتصل بدون البادئة &lt;module_name&gt;:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">mod</span> <span class="kn">import</span> <span class="n">s</span><span class="p">,</span> <span class="n">foo</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">s</span>
<span class="go">'If Comrade Napoleon says it, it must be right.'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foo</span><span class="p">(</span><span class="s1">'quux'</span><span class="p">)</span>
<span class="go">arg = quux</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">mod</span> <span class="kn">import</span> <span class="n">Foo</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span>
<span class="go">&lt;mod.Foo object at 0x02E3AD50&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">نظرًا لأن هذا النموذج من الاستيراد يضع أسماء الكائنات مباشرة في جدول رموز المتصل ، فسيتم استبدال أي كائنات موجودة بالفعل بنفس الاسم:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'foo'</span><span class="p">,</span> <span class="s1">'bar'</span><span class="p">,</span> <span class="s1">'baz'</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">a</span>
<span class="go">['foo', 'bar', 'baz']</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">mod</span> <span class="kn">import</span> <span class="n">a</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">a</span>
<span class="go">[100, 200, 300]</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">حتى أنه من الممكن استيراد كل شيء بشكل عشوائي من وحدة بضربة واحدة:<br />
</span></p>
<pre><code><span class="kn">from</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span> <span class="kn">import</span> <span class="o">*</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">سيؤدي هذا إلى وضع أسماء جميع الكائنات من &lt;module_name&gt; في جدول الرموز المحلي ، باستثناء أي منها يبدأ بحرف التسطير السفلي (_).</p>
<p>فمثلا:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">mod</span> <span class="kn">import</span> <span class="o">*</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">s</span>
<span class="go">'If Comrade Napoleon says it, it must be right.'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">a</span>
<span class="go">[100, 200, 300]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foo</span>
<span class="go">&lt;function foo at 0x03B449C0&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Foo</span>
<span class="go">&lt;class 'mod.Foo'&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لا ينصح بهذا بالضرورة في كود الإنتاج على نطاق واسع. إنه أمر خطير بعض الشيء لأنك تقوم بإدخال الأسماء في جدول الرموز المحلي بشكل جماعي. ما لم تكن تعرفهم جميعًا جيدًا ويمكن أن تكون واثقًا من أنه لن يكون هناك تعارض ، فلديك فرصة جيدة للكتابة فوق اسم موجود عن غير قصد. ومع ذلك ، فإن بناء الجملة هذا مفيد جدًا عندما تتجول فقط مع المترجم التفاعلي ، لأغراض الاختبار أو الاكتشاف ، لأنه يتيح لك الوصول بسرعة إلى كل ما تقدمه الوحدة دون الكثير من الكتابة.</p>
<p><strong>من &lt;module_name&gt; استيراد &lt;name&gt; كـ &lt;alt_name&gt;</strong></p>
<p>من الممكن أيضًا استيراد كائنات فردية ولكن إدخالها في جدول الرموز المحلي بأسماء بديلة:<br />
</span></p>
<pre><code><span class="kn">from</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span> <span class="kn">import</span> <span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span> <span class="k">as</span> <span class="o">&lt;</span><span class="n">alt_name</span><span class="o">&gt;</span><span class="p">[,</span> <span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span> <span class="k">as</span> <span class="o">&lt;</span><span class="n">alt_name</span><span class="o">&gt;</span> <span class="err">…</span><span class="p">]</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هذا يجعل من الممكن وضع الأسماء مباشرة في جدول الرموز المحلي ولكن تجنب التعارض مع الأسماء الموجودة سابقًا:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">s</span> <span class="o">=</span> <span class="s1">'foo'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'foo'</span><span class="p">,</span> <span class="s1">'bar'</span><span class="p">,</span> <span class="s1">'baz'</span><span class="p">]</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">mod</span> <span class="kn">import</span> <span class="n">s</span> <span class="k">as</span> <span class="n">string</span><span class="p">,</span> <span class="n">a</span> <span class="k">as</span> <span class="n">alist</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">s</span>
<span class="go">'foo'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">string</span>
<span class="go">'If Comrade Napoleon says it, it must be right.'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">a</span>
<span class="go">['foo', 'bar', 'baz']</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">alist</span>
<span class="go">[100, 200, 300]</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>استيراد &lt;module_name&gt; كـ &lt;alt_name&gt;</strong></p>
<p>يمكنك أيضًا استيراد وحدة كاملة تحت اسم بديل:<br />
</span></p>
<pre><code><span class="kn">import</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span> <span class="k">as</span> <span class="o">&lt;</span><span class="n">alt_name</span><span class="o">&gt;</span></code></pre>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span> <span class="k">as</span> <span class="nn">my_module</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">my_module</span><span class="o">.</span><span class="n">a</span>
<span class="go">[100, 200, 300]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">my_module</span><span class="o">.</span><span class="n">foo</span><span class="p">(</span><span class="s1">'qux'</span><span class="p">)</span>
<span class="go">arg = qux</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن استيراد محتويات الوحدة النمطية من داخل تعريف دالة. في هذه الحالة ، لا يتم الاستيراد حتى يتم استدعاء الوظيفة:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">bar</span><span class="p">():</span>
<span class="gp">... </span>    <span class="kn">from</span> <span class="nn">mod</span> <span class="kn">import</span> <span class="n">foo</span>
<span class="gp">... </span>    <span class="n">foo</span><span class="p">(</span><span class="s1">'corge'</span><span class="p">)</span>
<span class="gp">...</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">bar</span><span class="p">()</span>
<span class="go">arg = corge</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ومع ذلك ، لا تسمح Python 3 ببناء جملة الاستيراد * العشوائي من داخل دالة:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">bar</span><span class="p">():</span>
<span class="gp">... </span>    <span class="kn">from</span> <span class="nn">mod</span> <span class="kn">import</span> <span class="o">*</span>
<span class="gp">...</span>
<span class="go">SyntaxError: import * only allowed at module level</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">أخيرًا ، يمكن استخدام عبارة try مع بند باستثناء ImportError للحماية من محاولات الاستيراد غير الناجحة:<br />
</span></p>
<div class="highlight python repl">
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="c1"># Non-existent module</span>
<span class="gp">... </span>    <span class="kn">import</span> <span class="nn">baz</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">'Module not found'</span><span class="p">)</span>
<span class="gp">...</span>

<span class="go">Module not found</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>    <span class="c1"># Existing module, but non-existent object</span>
<span class="gp">... </span>    <span class="kn">from</span> <span class="nn">mod</span> <span class="kn">import</span> <span class="n">baz</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">ImportError</span><span class="p">:</span>
<span class="gp">... </span>    <span class="nb">print</span><span class="p">(</span><span class="s1">'Object not found in module'</span><span class="p">)</span>
<span class="gp">...</span>

<span class="go">Object not found in module</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">دالة دير ()</span></strong></p>
<p>ترجع الدالة المضمنة dir () قائمة بالأسماء المعرفة في مساحة اسم. بدون وسيطات ، ينتج قائمة بالأسماء مرتبة أبجديًا في جدول الرموز المحلي الحالي:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__']</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">qux</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__', 'qux']</span>

<span class="gp">&gt;&gt;&gt; </span><span class="k">class</span> <span class="nc">Bar</span><span class="p">():</span>
<span class="gp">... </span>    <span class="k">pass</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Bar</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['Bar', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__', 'qux', 'x']</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ كيف أن الاستدعاء الأول لـ dir () أعلاه يسرد عدة أسماء تم تحديدها تلقائيًا وفي مساحة الاسم بالفعل عند بدء المترجم. نظرًا لتعريف الأسماء الجديدة (qux ، Bar ، x) ، فإنها تظهر في الاستدعاءات اللاحقة لـ dir ().</p>
<p>يمكن أن يكون هذا مفيدًا لتحديد ما تمت إضافته إلى مساحة الاسم بالضبط بواسطة عبارة الاستيراد:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__']</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__', 'mod']</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod</span><span class="o">.</span><span class="n">s</span>
<span class="go">'If Comrade Napoleon says it, it must be right.'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod</span><span class="o">.</span><span class="n">foo</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span>
<span class="go">arg = [1, 2, 3]</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">mod</span> <span class="kn">import</span> <span class="n">a</span><span class="p">,</span> <span class="n">Foo</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['Foo', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__', 'a', 'mod']</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">a</span>
<span class="go">[100, 200, 300]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span>
<span class="go">&lt;mod.Foo object at 0x002EAD50&gt;</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">mod</span> <span class="kn">import</span> <span class="n">s</span> <span class="k">as</span> <span class="n">string</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['Foo', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__', 'a', 'mod', 'string', 'x']</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">string</span>
<span class="go">'If Comrade Napoleon says it, it must be right.'</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عند إعطاء وسيطة هي اسم الوحدة ، يسرد dir () الأسماء المحددة في الوحدة:<br />
</span></p>
<div class="highlight python repl">
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
<span class="go">['Foo', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__',</span>
<span class="go">'__name__', '__package__', '__spec__', 'a', 'foo', 's']</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__']</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">mod</span> <span class="kn">import</span> <span class="o">*</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['Foo', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__', 'a', 'foo', 's']</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">تنفيذ وحدة كبرنامج نصي</span></strong></p>
<p>أي ملف .py يحتوي على وحدة هو في الأساس برنامج نصي بلغة Python ، وليس هناك أي سبب لعدم تنفيذه مثل أحد.</p>
<p>هنا مرة أخرى هو mod.py كما تم تعريفه أعلاه:</p>
<p><strong>mod.py</strong><br />
</span></p>
<pre><code><span class="n">s</span> <span class="o">=</span> <span class="s2">"If Comrade Napoleon says it, it must be right."</span>
<span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">100</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">300</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'arg = </span><span class="si">{</span><span class="n">arg</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
    <span class="k">pass</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن تشغيل هذا كبرنامج نصي:<br />
</span></p>
<pre><code><span class="gp">C:\Users\john\Documents&gt;</span>python mod.py
<span class="gp">C:\Users\john\Documents&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لا توجد أخطاء ، لذلك يبدو أنها عملت. صحيح أنها ليست ممتعة للغاية. كما هو مكتوب ، فإنه يحدد الأشياء فقط. لا يفعل أي شيء معهم ، ولا ينتج عنه أي ناتج.</p>
<p>دعنا نعدل وحدة Python أعلاه بحيث تولد بعض المخرجات عند تشغيلها كبرنامج نصي:</p>
<p><strong>mod.py</strong><br />
</span></p>
<pre><code><span class="n">s</span> <span class="o">=</span> <span class="s2">"If Comrade Napoleon says it, it must be right."</span>
<span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">100</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">300</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'arg = </span><span class="si">{</span><span class="n">arg</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
    <span class="k">pass</span>

<span class="nb">print</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="n">foo</span><span class="p">(</span><span class="s1">'quux'</span><span class="p">)</span>
<span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الآن يجب أن يكون الأمر أكثر إثارة للاهتمام:</span></p>
<pre><code><span class="gp">C:\Users\john\Documents&gt;</span>python mod.py
<span class="go">If Comrade Napoleon says it, it must be right.</span>
<span class="go">[100, 200, 300]</span>
<span class="go">arg = quux</span>
<span class="gp">&lt;__main__.Foo object at 0x02F101D0&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لسوء الحظ ، يقوم الآن أيضًا بإنشاء مخرجات عند استيراده كوحدة نمطية:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>
<span class="go">If Comrade Napoleon says it, it must be right.</span>
<span class="go">[100, 200, 300]</span>
<span class="go">arg = quux</span>
<span class="go">&lt;mod.Foo object at 0x0169AD50&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هذا هو على الارجح ليس ما تريد. ليس من المعتاد لوحدة أن تولد مخرجات عند استيرادها.</p>
<p>ألن يكون من الجيد التمييز بين وقت تحميل الملف كوحدة وبين تشغيله كبرنامج نصي مستقل؟</p>
<p>اسأل وسوف تأخذ.</p>
<p>عندما يتم استيراد ملف .py كوحدة نمطية ، تعيّن Python المتغير الغامض الخاص __name__ لاسم الوحدة. ومع ذلك ، إذا تم تشغيل ملف كبرنامج نصي مستقل ، فسيتم تعيين __name__ (بشكل إبداعي) على السلسلة &#8220;__main__&#8221;. باستخدام هذه الحقيقة ، يمكنك تمييز الحالة في وقت التشغيل وتغيير السلوك وفقًا لذلك:</p>
<p><strong>mod.py</strong><br />
</span></p>
<pre><code><span class="n">s</span> <span class="o">=</span> <span class="s2">"If Comrade Napoleon says it, it must be right."</span>
<span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">100</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">300</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span>
    <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'arg = </span><span class="si">{</span><span class="n">arg</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
    <span class="k">pass</span>

<span class="k">if</span> <span class="p">(</span><span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">):</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'Executing as standalone script'</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
    <span class="n">foo</span><span class="p">(</span><span class="s1">'quux'</span><span class="p">)</span>
    <span class="n">x</span> <span class="o">=</span> <span class="n">Foo</span><span class="p">()</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الآن ، إذا قمت بتشغيل كبرنامج نصي ، فستحصل على الإخراج:<br />
</span></p>
<pre><code><span class="gp">C:\Users\john\Documents&gt;</span>python mod.py
<span class="go">Executing as standalone script</span>
<span class="go">If Comrade Napoleon says it, it must be right.</span>
<span class="go">[100, 200, 300]</span>
<span class="go">arg = quux</span>
<span class="gp">&lt;__main__.Foo object at 0x03450690&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ولكن إذا قمت بالاستيراد كوحدة نمطية ، فلن تقوم بما يلي:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod</span><span class="o">.</span><span class="n">foo</span><span class="p">(</span><span class="s1">'grault'</span><span class="p">)</span>
<span class="go">arg = grault</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">غالبًا ما يتم تصميم الوحدات النمطية مع القدرة على التشغيل كنصوص مستقل لأغراض اختبار الوظائف الموجودة في الوحدة النمطية. يشار إلى هذا باسم اختبار الوحدة. على سبيل المثال ، لنفترض أنك أنشأت حقيقة وحدة نمطية تحتوي على دالة مضروب ، على النحو التالي:</p>
<p><strong>fact.py</strong><br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">fact</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
    <span class="k">return</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">1</span> <span class="k">else</span> <span class="n">n</span> <span class="o">*</span> <span class="n">fact</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>

<span class="k">if</span> <span class="p">(</span><span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">):</span>
    <span class="kn">import</span> <span class="nn">sys</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="n">fact</span><span class="p">(</span><span class="nb">int</span><span class="p">(</span><span class="n">sys</span><span class="o">.</span><span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">])))</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن التعامل مع الملف كوحدة نمطية ، واستيراد وظيفة fact ():<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">fact</span> <span class="kn">import</span> <span class="n">fact</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">fact</span><span class="p">(</span><span class="mi">6</span><span class="p">)</span>
<span class="go">720</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ولكن يمكن أيضًا تشغيله كمستقل عن طريق تمرير وسيطة عدد صحيح في سطر الأوامر للاختبار:<br />
</span></p>
<pre><code><span class="gp">C:\Users\john\Documents&gt;</span>python fact.py 6
<span class="go">720</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">إعادة تحميل وحدة</span></strong></p>
<p>لأسباب تتعلق بالكفاءة ، يتم تحميل الوحدة مرة واحدة فقط لكل جلسة مترجم. هذا جيد بالنسبة لتعريفات الوظائف والفئات ، والتي عادة ما تشكل الجزء الأكبر من محتويات الوحدة. ولكن يمكن أن تحتوي الوحدة النمطية أيضًا على عبارات قابلة للتنفيذ ، عادةً للتهيئة. اعلم أنه سيتم تنفيذ هذه العبارات فقط في المرة الأولى التي يتم فيها استيراد وحدة نمطية.</p>
<p>ضع في اعتبارك ملف mod.py التالي:</p>
<p><strong>mod.py</strong><br />
</span></p>
<div class="highlight python">
<pre><code><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">100</span><span class="p">,</span> <span class="mi">200</span><span class="p">,</span> <span class="mi">300</span><span class="p">]</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'a ='</span><span class="p">,</span> <span class="n">a</span><span class="p">)</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>
<span class="go">a = [100, 200, 300]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">mod</span><span class="o">.</span><span class="n">a</span>
<span class="go">[100, 200, 300]</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لا يتم تنفيذ جملة print () على عمليات الاستيراد اللاحقة. (بالنسبة لهذه المسألة ، لا يوجد بيان الإسناد ، ولكن كما يظهر العرض النهائي لقيمة mod.a ، فإن هذا لا يهم. بمجرد إجراء المهمة ، فإنها تظل ثابتة.)</p>
<p>إذا قمت بإجراء تغيير على وحدة ما وتحتاج إلى إعادة تحميلها ، فأنت بحاجة إما إلى إعادة تشغيل المترجم الفوري أو استخدام وظيفة تسمى إعادة التحميل () من الوحدة importlib:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>
<span class="go">a = [100, 200, 300]</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">mod</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">importlib</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">importlib</span><span class="o">.</span><span class="n">reload</span><span class="p">(</span><span class="n">mod</span><span class="p">)</span>
<span class="go">a = [100, 200, 300]</span>
<span class="go">&lt;module 'mod' from 'C:\\Users\\john\\Documents\\Python\\doc\\mod.py'&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">حزم بايثون</span></strong></p>
<p>لنفترض أنك طورت تطبيقًا كبيرًا جدًا يتضمن العديد من الوحدات. مع نمو عدد الوحدات ، يصبح من الصعب تتبعها جميعًا إذا تم إلقاؤها في مكان واحد. هذا صحيح بشكل خاص إذا كانت لديهم أسماء أو وظائف مماثلة. قد ترغب في وسيلة لتجميعهم وتنظيمهم.</p>
<p>تسمح الحزم بهيكلة هرمية لمساحة اسم الوحدة النمطية باستخدام تدوين النقطة. بالطريقة نفسها التي تساعد بها الوحدات النمطية في تجنب التضارب بين أسماء المتغيرات العامة ، تساعد الحزم في تجنب التصادم بين أسماء الوحدات.</p>
<p>يعد إنشاء حزمة أمرًا سهلاً للغاية ، حيث إنه يستخدم بنية الملفات الهرمية المتأصلة في نظام التشغيل. ضع في اعتبارك الترتيب التالي:<br />
</span></p>
<p><a href="https://files.realpython.com/media/pkg1.9af1c7aea48f.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block  aligncenter" src="https://files.realpython.com/media/pkg1.9af1c7aea48f.png" alt="Image of a Python package" width="177" height="139" /></a></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هنا ، يوجد دليل باسم pkg يحتوي على وحدتين ، mod1.py و mod2.py. محتويات الوحدات هي:</p>
<p><strong>mod1.py</strong><br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'[mod1] foo()'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
    <span class="k">pass</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>mod2.py</strong></span><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">bar</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'[mod2] bar()'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Bar</span><span class="p">:</span>
    <span class="k">pass</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بالنظر إلى هذه البنية ، إذا كان دليل pkg موجودًا في مكان يمكن العثور عليه فيه (في أحد الأدلة الموجودة في sys.path) ، فيمكنك الرجوع إلى الوحدتين باستخدام تدوين النقطة (pkg.mod1 ، pkg.mod2) و قم باستيرادها بالصيغة التي تعرفها بالفعل:<br />
</span></p>
<div class="highlight python">
<pre><code><span class="kn">import</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span><span class="p">[,</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span> <span class="o">...</span><span class="p">]</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<div class="highlight python repl">
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">pkg.mod1</span><span class="o">,</span> <span class="nn">pkg.mod2</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pkg</span><span class="o">.</span><span class="n">mod1</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span>
<span class="go">[mod1] foo()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">pkg</span><span class="o">.</span><span class="n">mod2</span><span class="o">.</span><span class="n">Bar</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span>
<span class="go">&lt;pkg.mod2.Bar object at 0x033F7290&gt;</span>
</code></pre>
</div>
<div class="highlight python">
<pre><code><span class="kn">from</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span> <span class="kn">import</span> <span class="o">&lt;</span><span class="n">name</span><span class="p">(</span><span class="n">s</span><span class="p">)</span><span class="o">&gt;</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<div class="highlight python repl">
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg.mod1</span> <span class="kn">import</span> <span class="n">foo</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foo</span><span class="p">()</span>
<span class="go">[mod1] foo()</span>
</code></pre>
</div>
<div class="highlight python">
<pre><code><span class="kn">from</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span> <span class="kn">import</span> <span class="o">&lt;</span><span class="n">name</span><span class="o">&gt;</span> <span class="k">as</span> <span class="o">&lt;</span><span class="n">alt_name</span><span class="o">&gt;</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg.mod2</span> <span class="kn">import</span> <span class="n">Bar</span> <span class="k">as</span> <span class="n">Qux</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span> <span class="o">=</span> <span class="n">Qux</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">x</span>
<span class="go">&lt;pkg.mod2.Bar object at 0x036DFFD0&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكنك استيراد وحدات مع هذه العبارات أيضًا:<br />
</span></p>
<div class="highlight python">
<pre><code><span class="kn">from</span> <span class="o">&lt;</span><span class="n">package_name</span><span class="o">&gt;</span> <span class="kn">import</span> <span class="o">&lt;</span><span class="n">modules_name</span><span class="o">&gt;</span><span class="p">[,</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span> <span class="o">...</span><span class="p">]</span>
<span class="kn">from</span> <span class="o">&lt;</span><span class="n">package_name</span><span class="o">&gt;</span> <span class="kn">import</span> <span class="o">&lt;</span><span class="n">module_name</span><span class="o">&gt;</span> <span class="k">as</span> <span class="o">&lt;</span><span class="n">alt_name</span><span class="o">&gt;</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg</span> <span class="kn">import</span> <span class="n">mod1</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod1</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span>
<span class="go">[mod1] foo()</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg</span> <span class="kn">import</span> <span class="n">mod2</span> <span class="k">as</span> <span class="n">quux</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">quux</span><span class="o">.</span><span class="n">bar</span><span class="p">()</span>
<span class="go">[mod2] bar()</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكنك أيضًا استيراد الحزمة تقنيًا:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">pkg</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pkg</span>
<span class="go">&lt;module 'pkg' (namespace)&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لكن هذا قليل الفائدة. على الرغم من أن هذا ، بالمعنى الدقيق للكلمة ، بيان بايثون صحيح نحويًا ، إلا أنه لا يقدم الكثير من أي شيء مفيد. على وجه الخصوص ، لا يضع أيًا من الوحدات النمطية في pkg في مساحة الاسم المحلية:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">pkg</span><span class="o">.</span><span class="n">mod1</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">"&lt;pyshell#34&gt;"</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
    <span class="n">pkg</span><span class="o">.</span><span class="n">mod1</span>
<span class="gr">AttributeError</span>: <span class="n">module 'pkg' has no attribute 'mod1'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pkg</span><span class="o">.</span><span class="n">mod1</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">"&lt;pyshell#35&gt;"</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
    <span class="n">pkg</span><span class="o">.</span><span class="n">mod1</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span>
<span class="gr">AttributeError</span>: <span class="n">module 'pkg' has no attribute 'mod1'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pkg</span><span class="o">.</span><span class="n">mod2</span><span class="o">.</span><span class="n">Bar</span><span class="p">()</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">"&lt;pyshell#36&gt;"</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
    <span class="n">pkg</span><span class="o">.</span><span class="n">mod2</span><span class="o">.</span><span class="n">Bar</span><span class="p">()</span>
<span class="gr">AttributeError</span>: <span class="n">module 'pkg' has no attribute 'mod2'</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاستيراد الوحدات أو محتوياتها فعليًا ، تحتاج إلى استخدام أحد النماذج الموضحة أعلاه.</p>
<p><strong><span style="font-size: 20pt">تهيئة الحزمة</span></strong></p>
<p>إذا كان الملف المسمى __init__.py موجودًا في دليل الحزمة ، فسيتم استدعاؤه عند استيراد الحزمة أو الوحدة النمطية في الحزمة. يمكن استخدام هذا لتنفيذ كود تهيئة الحزمة ، مثل تهيئة بيانات مستوى الحزمة.</p>
<p>على سبيل المثال ، ضع في اعتبارك ملف __init__.py التالي:</p>
<p><strong>__init__.py</strong><br />
</span></p>
<pre><code><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'Invoking __init__.py for </span><span class="si">{</span><span class="vm">__name__</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
<span class="n">A</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'quux'</span><span class="p">,</span> <span class="s1">'corge'</span><span class="p">,</span> <span class="s1">'grault'</span><span class="p">]</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لنضيف هذا الملف إلى دليل pkg من المثال أعلاه:</span></p>
<p><a href="https://files.realpython.com/media/pkg2.dab97c2f9c58.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block  aligncenter" src="https://files.realpython.com/media/pkg2.dab97c2f9c58.png" alt="Illustration of hierarchical file structure of Python packages" width="221" height="181" /></a></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الآن عند استيراد الحزمة ، يتم تهيئة القائمة العامة A:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">pkg</span>
<span class="go">Invoking __init__.py for pkg</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pkg</span><span class="o">.</span><span class="n">A</span>
<span class="go">['quux', 'corge', 'grault']</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن لوحدة نمطية في الحزمة الوصول إلى المتغير العام عن طريق استيرادها بدوره:</p>
<p><strong>mod1.py</strong><br />
</span></p>
<div class="highlight python">
<pre><code><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
    <span class="kn">from</span> <span class="nn">pkg</span> <span class="kn">import</span> <span class="n">A</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'[mod1] foo() / A = '</span><span class="p">,</span> <span class="n">A</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
    <span class="k">pass</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg</span> <span class="kn">import</span> <span class="n">mod1</span>
<span class="go">Invoking __init__.py for pkg</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod1</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span>
<span class="go">[mod1] foo() / A =  ['quux', 'corge', 'grault']</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن أيضًا استخدام __init__.py لإحداث استيراد تلقائي للوحدات من الحزمة. على سبيل المثال ، رأيت سابقًا أن العبارة import pkg تضع الاسم pkg فقط في جدول الرموز المحلي للمتصل ولا تستورد أي وحدات. ولكن إذا كان __init__.py في دليل pkg يحتوي على ما يلي:</p>
<p><strong>__init__.py</strong><br />
</span></p>
<pre><code><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'Invoking __init__.py for </span><span class="si">{</span><span class="vm">__name__</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">pkg.mod1</span><span class="o">,</span> <span class="nn">pkg.mod2</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عند تنفيذ استيراد pkg ، يتم استيراد الوحدتين mod1 و mod2 تلقائيًا:</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">pkg</span>
<span class="go">Invoking __init__.py for pkg</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pkg</span><span class="o">.</span><span class="n">mod1</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span>
<span class="go">[mod1] foo()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pkg</span><span class="o">.</span><span class="n">mod2</span><span class="o">.</span><span class="n">bar</span><span class="p">()</span>
<span class="go">[mod2] bar()</span>
</code></pre>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ملاحظة: تنص الكثير من وثائق Python على أن ملف __init__.py يجب أن يكون موجودًا في دليل الحزمة عند إنشاء حزمة. كان هذا صحيحًا في يوم من الأيام. اعتاد أن يكون وجود __init__.py يشير إلى Python أنه تم تعريف الحزمة. يمكن أن يحتوي الملف على رمز تهيئة أو قد يكون فارغًا ، ولكن يجب أن يكون موجودًا.</p>
<p>بدءًا من Python 3.3 ، تم تقديم حزم Namespace الضمنية. يسمح ذلك بإنشاء حزمة بدون أي ملف __init__.py. بالطبع ، يمكن أن يظل موجودًا إذا كانت هناك حاجة إلى تهيئة الحزمة. لكنها لم تعد مطلوبة.<br />
</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">استيراد * من حزمة</span></strong></p>
<p>لأغراض المناقشة التالية ، يتم توسيع الحزمة المحددة مسبقًا لتشمل بعض الوحدات النمطية الإضافية:</span></p>
<p><a href="https://files.realpython.com/media/pkg3.d2160908ae77.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block  aligncenter" src="https://files.realpython.com/media/pkg3.d2160908ae77.png" alt="Illustration of hierarchical file structure of Python packages" width="177" height="223" /></a></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يوجد الآن أربع وحدات معرفة في دليل pkg. محتوياتها كما هو موضح أدناه:</p>
<p><strong>mod1.py</strong><br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'[mod1] foo()'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
    <span class="k">pass</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><br />
<strong>mod2.py</strong><br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">bar</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'[mod2] bar()'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Bar</span><span class="p">:</span>
    <span class="k">pass</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><br />
<strong>mod3.py</strong><br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">baz</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'[mod3] baz()'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Baz</span><span class="p">:</span>
    <span class="k">pass</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><br />
<strong>mod4.py</strong><br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">qux</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'[mod4] qux()'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Qux</span><span class="p">:</span>
    <span class="k">pass</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">(خيالي ، أليس كذلك؟)</p>
<p>لقد رأيت بالفعل أنه عند استخدام الاستيراد * لوحدة نمطية ، يتم استيراد جميع الكائنات من الوحدة النمطية إلى جدول الرموز المحلي ، باستثناء تلك التي تبدأ أسماؤها بشرطة سفلية ، كما هو الحال دائمًا:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__']</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg.mod3</span> <span class="kn">import</span> <span class="o">*</span>

<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['Baz', '__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__', 'baz']</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">baz</span><span class="p">()</span>
<span class="go">[mod3] baz()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Baz</span>
<span class="go">&lt;class 'pkg.mod3.Baz'&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">البيان المقابل للحزمة هو:<br />
</span></p>
<pre><code><span class="kn">from</span> <span class="o">&lt;</span><span class="n">package_name</span><span class="o">&gt;</span> <span class="kn">import</span> <span class="o">*</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ماذا يفعل ذلك؟<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__']</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg</span> <span class="kn">import</span> <span class="o">*</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__']</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">همف. ليس كثيرا. ربما كنت تتوقع (بافتراض أن لديك أي توقعات على الإطلاق) أن بايثون ستغوص في دليل الحزم ، وتجد كل الوحدات التي يمكنها ذلك ، وتستوردها جميعًا. لكن كما ترى ، هذا ليس ما يحدث بشكل افتراضي.</p>
<p>بدلاً من ذلك ، تتبع Python هذا الاصطلاح: إذا كان الملف __init__.py في دليل الحزمة يحتوي على قائمة باسم __all__ ، فسيتم اعتبارها قائمة بالوحدات التي يجب استيرادها عند مواجهة العبارة من &lt;package_name&gt; import *.</p>
<p>في المثال الحالي ، افترض أنك أنشأت __init__.py في دليل pkg مثل هذا:</p>
<p><strong>pkg / __ init__.py</strong><br />
</span></p>
<pre><code><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span>
        <span class="s1">'mod1'</span><span class="p">,</span>
        <span class="s1">'mod2'</span><span class="p">,</span>
        <span class="s1">'mod3'</span><span class="p">,</span>
        <span class="s1">'mod4'</span>
        <span class="p">]</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الآن من استيراد pkg * يستورد جميع الوحدات الأربع:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__']</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg</span> <span class="kn">import</span> <span class="o">*</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__', 'mod1', 'mod2', 'mod3', 'mod4']</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod2</span><span class="o">.</span><span class="n">bar</span><span class="p">()</span>
<span class="go">[mod2] bar()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod4</span><span class="o">.</span><span class="n">Qux</span>
<span class="go">&lt;class 'pkg.mod4.Qux'&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لا يزال استخدام الاستيراد * لا يُعتبر شكلاً رائعًا ، أكثر من الحزم مقارنة بالوحدات النمطية. لكن هذه الميزة على الأقل تمنح منشئ الحزمة بعض التحكم فيما يحدث عند تحديد الاستيراد *. (في الواقع ، يوفر القدرة على عدم السماح به تمامًا ، ببساطة عن طريق رفض تعريف __all__ على الإطلاق. كما رأيت ، فإن السلوك الافتراضي للحزم هو عدم استيراد أي شيء.)</p>
<p>بالمناسبة ، يمكن تعريف __all__ في وحدة أيضًا ويخدم نفس الغرض: للتحكم في ما يتم استيراده مع الاستيراد *. على سبيل المثال ، قم بتعديل mod1.py على النحو التالي:</p>
<p><strong>pkg / mod1.py</strong><br />
</span></p>
<pre><code><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'foo'</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'[mod1] foo()'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
    <span class="k">pass</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الآن ستقوم عبارة import * من pkg.mod1 باستيراد ما هو وارد في __all__:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__']</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg.mod1</span> <span class="kn">import</span> <span class="o">*</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">()</span>
<span class="go">['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__',</span>
<span class="go">'__package__', '__spec__', 'foo']</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">foo</span><span class="p">()</span>
<span class="go">[mod1] foo()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">Foo</span>
<span class="gt">Traceback (most recent call last):</span>
  File <span class="nb">"&lt;pyshell#37&gt;"</span>, line <span class="m">1</span>, in <span class="n">&lt;module&gt;</span>
    <span class="n">Foo</span>
<span class="gr">NameError</span>: <span class="n">name 'Foo' is not defined</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">foo () (الوظيفة) مُعرَّفة الآن في مساحة الاسم المحلية ، ولكن Foo (الفئة) ليست كذلك ، لأن الأخير ليس في __all__.</p>
<p>باختصار ، يتم استخدام __all__ بواسطة كلٍ من الحزم والوحدات للتحكم في ما يتم استيراده عند تحديد الاستيراد *. لكن السلوك الافتراضي يختلف:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بالنسبة للحزمة ، عندما لا يتم تعريف __all__ ، لا يستورد الاستيراد * أي شيء.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بالنسبة إلى وحدة نمطية ، عندما لا يتم تعريف __all__ ، يقوم الاستيراد * باستيراد كل شيء (باستثناء &#8211; كما خمنت &#8211; الأسماء التي تبدأ بشرطة سفلية).<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">الحزم الفرعية</span></strong></p>
<p>يمكن أن تحتوي الحزم على حزم فرعية متداخلة إلى عمق عشوائي. على سبيل المثال ، دعونا نجري تعديلًا آخر على مثال دليل الحزمة على النحو التالي:</span></p>
<p><a href="https://files.realpython.com/media/pkg4.a830d6e144bf.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block  aligncenter" src="https://files.realpython.com/media/pkg4.a830d6e144bf.png" alt="Illustration of hierarchical file structure of Python packages" width="229" height="317" /></a></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تم تعريف الوحدات الأربعة (mod1.py و mod2.py و mod3.py و mod4.py) على النحو السابق. ولكن الآن ، بدلاً من تجميعها معًا في دليل pkg ، يتم تقسيمها إلى مجلدين فرعيين ، sub_pkg1 و sub_pkg2.</p>
<p>لا يزال الاستيراد يعمل كما هو موضح سابقًا. بناء الجملة مشابه ، ولكن يتم استخدام تدوين نقطي إضافي لفصل اسم الحزمة عن اسم الحزمة الفرعية:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">pkg.sub_pkg1.mod1</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">pkg</span><span class="o">.</span><span class="n">sub_pkg1</span><span class="o">.</span><span class="n">mod1</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span>
<span class="go">[mod1] foo()</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg.sub_pkg1</span> <span class="kn">import</span> <span class="n">mod2</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod2</span><span class="o">.</span><span class="n">bar</span><span class="p">()</span>
<span class="go">[mod2] bar()</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg.sub_pkg2.mod3</span> <span class="kn">import</span> <span class="n">baz</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">baz</span><span class="p">()</span>
<span class="go">[mod3] baz()</span>

<span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg.sub_pkg2.mod4</span> <span class="kn">import</span> <span class="n">qux</span> <span class="k">as</span> <span class="n">grault</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">grault</span><span class="p">()</span>
<span class="go">[mod4] qux()</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بالإضافة إلى ذلك ، يمكن للوحدة في حزمة فرعية واحدة أن تشير إلى كائنات في حزمة فرعية للأشقاء (في حالة احتواء الأخوة على بعض الوظائف التي تحتاجها). على سبيل المثال ، افترض أنك تريد استيراد وظيفة foo () وتنفيذها (محددة في الوحدة النمطية 1) من داخل الوحدة النمطية 3. يمكنك إما استخدام استيراد مطلق:</p>
<p><strong>pkg / sub__pkg2 / mod3.py</strong><br />
</span></p>
<div class="highlight python">
<pre><code><span class="k">def</span> <span class="nf">baz</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'[mod3] baz()'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Baz</span><span class="p">:</span>
    <span class="k">pass</span>

<span class="kn">from</span> <span class="nn">pkg.sub_pkg1.mod1</span> <span class="kn">import</span> <span class="n">foo</span>
<span class="n">foo</span><span class="p">()</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg.sub_pkg2</span> <span class="kn">import</span> <span class="n">mod3</span>
<span class="go">[mod1] foo()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">mod3</span><span class="o">.</span><span class="n">foo</span><span class="p">()</span>
<span class="go">[mod1] foo()</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">أو يمكنك استخدام استيراد نسبي ، حيث .. يشير إلى الحزمة ذات المستوى الأعلى. من داخل mod3.py ، الموجودة في الحزمة الفرعية sub_pkg2 ،<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">.. يقيّم الحزمة الأصلية (pkg) ، و<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يتم تقييم ..sub_pkg1 إلى subpackage sub_pkg1 من الحزمة الرئيسية.<br />
</span></li>
</ul>
<p><strong><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">pkg / sub__pkg2 / mod3.py</span></strong><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><br />
</span></p>
<div class="highlight python">
<pre><code><span class="k">def</span> <span class="nf">baz</span><span class="p">():</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'[mod3] baz()'</span><span class="p">)</span>

<span class="k">class</span> <span class="nc">Baz</span><span class="p">:</span>
    <span class="k">pass</span>

<span class="kn">from</span> <span class="nn">..</span> <span class="kn">import</span> <span class="n">sub_pkg1</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sub_pkg1</span><span class="p">)</span>

<span class="kn">from</span> <span class="nn">..sub_pkg1.mod1</span> <span class="kn">import</span> <span class="n">foo</span>
<span class="n">foo</span><span class="p">()</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">pkg.sub_pkg2</span> <span class="kn">import</span> <span class="n">mod3</span>
<span class="go">&lt;module 'pkg.sub_pkg1' (namespace)&gt;</span>
<span class="go">[mod1] foo()</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">خاتمة</span></strong></p>
<p>لقد غطيت في هذا البرنامج التعليمي المواضيع التالية:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كيفية إنشاء وحدة Python<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">المواقع التي يبحث فيها مترجم Python عن وحدة نمطية<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كيفية الوصول إلى الكائنات المحددة في وحدة نمطية مع بيان الاستيراد<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كيفية إنشاء وحدة قابلة للتنفيذ كبرنامج نصي مستقل<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كيفية تنظيم الوحدات في حزم وحزم فرعية<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كيفية التحكم في تهيئة الحزمة<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">نأمل أن يتيح لك ذلك فهمًا أفضل لكيفية الوصول إلى الوظائف المتاحة في العديد من الوحدات النمطية التابعة للجهات الخارجية والمدمجة المتوفرة في Python.</p>
<p>بالإضافة إلى ذلك ، إذا كنت تقوم بتطوير التطبيق الخاص بك ، فإن إنشاء الوحدات والحزم الخاصة بك سيساعدك على تنظيم التعليمات البرمجية الخاصة بك وجعلها نموذجية ، مما يجعل الترميز والصيانة وتصحيح الأخطاء أسهل.</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span class="" title="">إذا كنت تريد معرفة المزيد ، فراجع الوثائق التالية على موقع Python.org:</span><br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span title="">نظام الاستيراد</span><br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span title="">دروس بايثون: الوحدات</span><br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span title="">بايثونينج سعيد!</span></span></p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d9%88%d8%ad%d8%af%d8%a7%d8%aa-%d9%88%d8%ad%d8%b2%d9%85-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-%d9%85%d9%82%d8%af%d9%85%d8%a9/">وحدات وحزم بايثون &#8211; مقدمة</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://arabdars.com/%d9%88%d8%ad%d8%af%d8%a7%d8%aa-%d9%88%d8%ad%d8%b2%d9%85-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86-%d9%85%d9%82%d8%af%d9%85%d8%a9/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>العمل مع بيانات JSON في بايثون</title>
		<link>https://arabdars.com/%d8%a7%d9%84%d8%b9%d9%85%d9%84-%d9%85%d8%b9-%d8%a8%d9%8a%d8%a7%d9%86%d8%a7%d8%aa-json-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/</link>
					<comments>https://arabdars.com/%d8%a7%d9%84%d8%b9%d9%85%d9%84-%d9%85%d8%b9-%d8%a8%d9%8a%d8%a7%d9%86%d8%a7%d8%aa-json-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/#respond</comments>
		
		<dc:creator><![CDATA[Reyhane]]></dc:creator>
		<pubDate>Sun, 20 Sep 2020 09:04:15 +0000</pubDate>
				<category><![CDATA[الماتلاب Matlab]]></category>
		<guid isPermaLink="false">https://arabdars.com/?p=1621</guid>

					<description><![CDATA[<p>جدول المحتويات تاريخ موجز (جدًا) لـ JSON انظروا ، إنه JSON! لغة Python تدعم JSON أصلاً! القليل من المفردات تسلسل JSON مثال بسيط على التسلسل بعض حجج الكلمات الرئيسية المفيدة إلغاء تسلسل JSON مثال بسيط على إلغاء التسلسل مثال من العالم الحقيقي (نوعًا ما) ترميز وفك ترميز كائنات Python المخصصة تبسيط هياكل البيانات ترميز أنواع [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d8%a7%d9%84%d8%b9%d9%85%d9%84-%d9%85%d8%b9-%d8%a8%d9%8a%d8%a7%d9%86%d8%a7%d8%aa-json-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/">العمل مع بيانات JSON في بايثون</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">جدول المحتويات<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تاريخ موجز (جدًا) لـ JSON<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">انظروا ، إنه JSON!<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لغة Python تدعم JSON أصلاً!<br />
القليل من المفردات<br />
تسلسل JSON<br />
مثال بسيط على التسلسل<br />
بعض حجج الكلمات الرئيسية المفيدة<br />
إلغاء تسلسل JSON<br />
مثال بسيط على إلغاء التسلسل<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">مثال من العالم الحقيقي (نوعًا ما)<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ترميز وفك ترميز كائنات Python المخصصة<br />
تبسيط هياكل البيانات<br />
ترميز أنواع مخصصة<br />
أنواع مخصصة فك التشفير<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كله تمام!<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">منذ نشأتها ، سرعان ما أصبحت JSON المعيار الفعلي لتبادل المعلومات. من المحتمل أنك هنا لأنك تحتاج إلى نقل بعض البيانات من هنا إلى هناك. من المحتمل أنك تجمع المعلومات من خلال واجهة برمجة التطبيقات أو تخزن بياناتك في قاعدة بيانات المستندات. بطريقة أو بأخرى ، ستصل إلى مستوى رقبتك في JSON ، ويجب عليك الخروج من Python.</p>
<p>لحسن الحظ ، هذه مهمة شائعة جدًا ، وكما هو الحال مع المهام الأكثر شيوعًا ، فإن بايثون تجعلها سهلة بشكل مثير للاشمئزاز. لا تخف يا رفاق بايثونير و بايثونيستاس. هذا سيكون نسيم!<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذن ، نستخدم JSON لتخزين البيانات وتبادلها؟ نعم ، لقد حصلت عليه! إنه ليس أكثر من تنسيق قياسي يستخدمه المجتمع لتمرير البيانات. ضع في اعتبارك أن JSON ليس التنسيق الوحيد المتاح لهذا النوع من العمل ، ولكن XML و YAML هما على الأرجح التنسيقان الآخران الوحيدان اللذان يستحق الذكر في نفس الوقت.</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">تاريخ موجز (جدًا) لـ JSON</span></strong></p>
<p>ليس من المستغرب أن JavaScript Object Notation مستوحى من مجموعة فرعية من لغة برمجة JavaScript التي تتعامل مع بناء الجملة الحرفية للكائن. لديهم موقع أنيق يشرح الأمر برمته. لا داعي للقلق: لقد أصبحت JSON منذ فترة طويلة حيادية اللغة وهي موجودة كمعيارها الخاص ، لذلك يمكننا لحسن الحظ تجنب JavaScript من أجل هذه المناقشة.</p>
<p>في النهاية ، اعتمد المجتمع ككل JSON لأنه من السهل على كل من البشر والآلات الإنشاء والفهم.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">انظروا ، إنه JSON!</span></strong></p>
<p>إستعد. أنا على وشك أن أريكم بعض صور JSON الواقعية &#8211; تمامًا كما كنت سترى هناك في البرية. لا بأس: من المفترض أن تكون لغة JSON قابلة للقراءة من قبل أي شخص يستخدم لغة من النمط C ، و Python هي لغة من النمط C &#8230; لذلك هذا أنت!<br />
</span></p>
<pre><code><span class="p">{</span>
    <span class="nt">"firstName"</span><span class="p">:</span> <span class="s2">"Jane"</span><span class="p">,</span>
    <span class="nt">"lastName"</span><span class="p">:</span> <span class="s2">"Doe"</span><span class="p">,</span>
    <span class="nt">"hobbies"</span><span class="p">:</span> <span class="p">[</span><span class="s2">"running"</span><span class="p">,</span> <span class="s2">"sky diving"</span><span class="p">,</span> <span class="s2">"singing"</span><span class="p">],</span>
    <span class="nt">"age"</span><span class="p">:</span> <span class="mi">35</span><span class="p">,</span>
    <span class="nt">"children"</span><span class="p">:</span> <span class="p">[</span>
        <span class="p">{</span>
            <span class="nt">"firstName"</span><span class="p">:</span> <span class="s2">"Alice"</span><span class="p">,</span>
            <span class="nt">"age"</span><span class="p">:</span> <span class="mi">6</span>
        <span class="p">},</span>
        <span class="p">{</span>
            <span class="nt">"firstName"</span><span class="p">:</span> <span class="s2">"Bob"</span><span class="p">,</span>
            <span class="nt">"age"</span><span class="p">:</span> <span class="mi">8</span>
        <span class="p">}</span>
    <span class="p">]</span>
<span class="p">}</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كما ترى ، يدعم JSON الأنواع الأولية ، مثل السلاسل والأرقام ، بالإضافة إلى القوائم والكائنات المتداخلة.<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">انتظر ، هذا يشبه قاموس بايثون! أنا أوافق؟ إنه رمز كائن عالمي إلى حد كبير في هذه المرحلة ، لكنني لا أعتقد أن UON يتدحرج على لسانه بشكل جيد تمامًا. لا تتردد في مناقشة البدائل في التعليقات.<br />
</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يا للعجب! لقد نجوت من مواجهتك الأولى مع بعض JSON البرية. الآن تحتاج فقط إلى تعلم كيفية ترويضها.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">لغة Python تدعم JSON أصلاً!</span></strong></p>
<p>تأتي Python مع حزمة مدمجة تسمى json لتشفير وفك تشفير بيانات JSON.</p>
<p>فقط ارمي هذا الرجل الصغير في أعلى الملف الخاص بك:<br />
</span></p>
<pre><code><span class="kn">import</span> <span class="nn">json</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>القليل من المفردات</strong></p>
<p>عادةً ما تسمى عملية تشفير JSON التسلسل. يشير هذا المصطلح إلى تحويل البيانات إلى سلسلة من البايتات (ومن ثم التسلسلية) ليتم تخزينها أو نقلها عبر الشبكة. قد تسمع أيضًا مصطلح التنظيم ، ولكن هذه مناقشة أخرى كاملة. بطبيعة الحال ، فإن إلغاء التسلسل هو عملية متبادلة لفك تشفير البيانات التي تم تخزينها أو تسليمها في معيار JSON.<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ييكيس! هذا يبدو تقنيًا جدًا. قطعا. لكن في الواقع ، كل ما نتحدث عنه هنا هو القراءة والكتابة. فكر في الأمر على هذا النحو: الترميز هو لكتابة البيانات على القرص ، بينما فك التشفير هو لقراءة البيانات في الذاكرة.</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>تسلسل JSON</strong></p>
<p>ماذا يحدث بعد معالجة الكمبيوتر للكثير من المعلومات؟ يجب أن تأخذ تفريغ البيانات. وفقًا لذلك ، تعرض مكتبة json طريقة التفريغ () لكتابة البيانات إلى الملفات. هناك أيضًا طريقة dumps () (تُنطق باسم &#8220;dump-s&#8221;) للكتابة إلى سلسلة Python.</p>
<p>يتم ترجمة كائنات Python البسيطة إلى JSON وفقًا لتحويل بديهي إلى حد ما.<br />
Python JSON<br />
كائن ديكت<br />
قائمة ، مجموعة الصفيف<br />
سلسلة str<br />
عدد صحيح ، طويل ، عائم<br />
حقيقي حقيقي<br />
خطأ خطأ<br />
لا شيء فارغ</p>
<p><strong>مثال بسيط على التسلسل</strong></p>
<p>تخيل أنك تعمل مع كائن Python في الذاكرة يبدو قليلاً مثل هذا:<br />
</span></p>
<pre><code><span class="n">data</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s2">"president"</span><span class="p">:</span> <span class="p">{</span>
        <span class="s2">"name"</span><span class="p">:</span> <span class="s2">"Zaphod Beeblebrox"</span><span class="p">,</span>
        <span class="s2">"species"</span><span class="p">:</span> <span class="s2">"Betelgeusian"</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">من الأهمية بمكان أن تقوم بحفظ هذه المعلومات على القرص ، لذا فإن مهمتك هي كتابتها في ملف.</p>
<p>باستخدام مدير سياق Python ، يمكنك إنشاء ملف يسمى data_file.json وفتحه في وضع الكتابة. (تنتهي ملفات JSON بسهولة بامتداد .json.)<br />
</span></p>
<pre><code><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"data_file.json"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span> <span class="k">as</span> <span class="n">write_file</span><span class="p">:</span>
    <span class="n">json</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">write_file</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ أن dump () يأخذ وسيطين موضعيين: (1) كائن البيانات المراد تسلسله ، و (2) الكائن الشبيه بالملف الذي سيتم كتابة البايت عليه.</p>
<p>أو ، إذا كنت تميل إلى الاستمرار في استخدام بيانات JSON المتسلسلة هذه في برنامجك ، فيمكنك كتابتها إلى كائن Python str أصلي.<br />
</span></p>
<pre><code><span class="n">json_string</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">)</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ أن الكائن الذي يشبه الملف غائب نظرًا لأنك لا تكتب فعليًا على القرص. بخلاف ذلك ، فإن عمليات التفريغ () تشبه تمامًا التفريغ ().</p>
<p>الصيحة! لقد أنجبت طفلاً JSON ، وأنت على استعداد لإطلاقه في البرية لتنمو بشكل كبير وقوي.<br />
</span></p>
<p><strong><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بعض حجج الكلمات الرئيسية المفيدة</span></strong></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تذكر أنه من المفترض أن تكون لغة JSON سهلة القراءة من قِبل البشر ، إلا أن البنية القابلة للقراءة لا تكفي إذا تم دمجها معًا. بالإضافة إلى أنه من المحتمل أن يكون لديك أسلوب برمجة مختلف عني ، وقد يكون من الأسهل بالنسبة لك قراءة التعليمات البرمجية عندما يتم تنسيقها حسب رغبتك.<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ملاحظة: كلا الأسلوبين dump () و dumps () تستخدمان نفس الوسيطات الأساسية.</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الخيار الأول الذي يريد معظم الناس تغييره هو المسافة البيضاء. يمكنك استخدام وسيطة الكلمة الأساسية للمسافة البادئة لتحديد حجم المسافة البادئة للبنى المتداخلة. تحقق من الاختلاف بنفسك باستخدام البيانات ، التي حددناها أعلاه ، وتشغيل الأوامر التالية في وحدة التحكم:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">خيار تنسيق آخر هو وسيطة الكلمات الأساسية الفواصل. بشكل افتراضي ، هذه هي مجموعتان من السلاسل الفاصلة (&#8220;،&#8221;، &#8220;:&#8221;) ، ولكن البديل الشائع لـ JSON المضغوط هو (&#8220;،&#8221;، &#8220;:&#8221;). ألقِ نظرة على نموذج JSON مرة أخرى لترى أين تلعب هذه الفواصل.</p>
<p>هناك آخرون ، مثل sort_keys ، لكن ليس لدي أي فكرة عما يفعله هذا الشخص. يمكنك العثور على قائمة كاملة في المستندات إذا كنت مهتمًا.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>إلغاء تسلسل JSON</strong></p>
<p>رائع ، يبدو أنك قد التقطت لنفسك بعض JSON البري! حان الوقت الآن لإضفاء الشكل. في مكتبة json ، ستجد load () و load () لتحويل البيانات المشفرة JSON إلى كائنات Python.</p>
<p>تمامًا مثل التسلسل ، يوجد جدول تحويل بسيط لإلغاء التسلسل ، على الرغم من أنه يمكنك على الأرجح تخمين كيف يبدو بالفعل.<br />
جسون بايثون<br />
كائن ديكت<br />
قائمة الصفيف<br />
سلسلة سلسلة<br />
عدد (كثافة العمليات)<br />
عدد (حقيقي) عائم<br />
حقيقي حقيقي<br />
خطأ خطأ<br />
لا شيء لا شيء</p>
<p>من الناحية الفنية ، لا يمثل هذا التحويل معكوسًا مثاليًا لجدول التسلسل. هذا يعني بشكل أساسي أنه إذا قمت بترميز كائن الآن ثم فك تشفيره مرة أخرى لاحقًا ، فقد لا تحصل على نفس الكائن مرة أخرى. أتخيل أنه يشبه إلى حد ما النقل الآني: قم بتكسير جزيئاتي هنا وإعادة تجميعها مرة أخرى هناك. هل ما زلت نفس الشخص؟</p>
<p>في الواقع ، ربما يكون الأمر أشبه بإقناع صديق بترجمة شيء ما إلى اليابانية وصديق آخر لترجمته مرة أخرى إلى اللغة الإنجليزية. بغض النظر ، فإن أبسط مثال هو ترميز tuple واستعادة قائمة بعد فك التشفير ، مثل:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">blackjack_hand</span> <span class="o">=</span> <span class="p">(</span><span class="mi">8</span><span class="p">,</span> <span class="s2">"Q"</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">encoded_hand</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">blackjack_hand</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">decoded_hand</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">encoded_hand</span><span class="p">)</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">blackjack_hand</span> <span class="o">==</span> <span class="n">decoded_hand</span>
<span class="go">False</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">blackjack_hand</span><span class="p">)</span>
<span class="go">&lt;class 'tuple'&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">decoded_hand</span><span class="p">)</span>
<span class="go">&lt;class 'list'&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">blackjack_hand</span> <span class="o">==</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">decoded_hand</span><span class="p">)</span>
<span class="go">True</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>مثال بسيط على إلغاء التسلسل</strong></p>
<p>هذه المرة ، تخيل أن لديك بعض البيانات المخزنة على القرص والتي ترغب في معالجتها في الذاكرة. ستظل تستخدم مدير السياق ، ولكن هذه المرة ستفتح ملف data_file.json الحالي في وضع القراءة.<br />
</span></p>
<pre><code><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"data_file.json"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="n">read_file</span><span class="p">:</span>
    <span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">load</span><span class="p">(</span><span class="n">read_file</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الأمور واضحة ومباشرة هنا ، ولكن ضع في اعتبارك أن نتيجة هذه الطريقة يمكن أن ترجع أيًا من أنواع البيانات المسموح بها من جدول التحويل. هذا مهم فقط إذا كنت تقوم بتحميل بيانات لم تراها من قبل. في معظم الحالات ، سيكون الكائن الجذر عبارة عن إملاء أو قائمة.</p>
<p>إذا كنت قد سحبت بيانات JSON من برنامج آخر أو حصلت بطريقة أخرى على سلسلة من البيانات بتنسيق JSON في Python ، فيمكنك إلغاء تسلسل ذلك بسهولة باستخدام الأحمال () ، والتي يتم تحميلها بشكل طبيعي من سلسلة:<br />
</span></p>
<pre><code><span class="n">json_string</span> <span class="o">=</span> <span class="s2">"""</span>
<span class="s2">{</span>
<span class="s2">    "researcher": {</span>
<span class="s2">        "name": "Ford Prefect",</span>
<span class="s2">        "species": "Betelgeusian",</span>
<span class="s2">        "relatives": [</span>
<span class="s2">            {</span>
<span class="s2">                "name": "Zaphod Beeblebrox",</span>
<span class="s2">                "species": "Betelgeusian"</span>
<span class="s2">            }</span>
<span class="s2">        ]</span>
<span class="s2">    }</span>
<span class="s2">}</span>
<span class="s2">"""</span>
<span class="n">data</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">json_string</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هاهو! لقد قمت بترويض JSON البري ، وهو الآن تحت سيطرتك. لكن ما تفعله بهذه القوة متروك لك. يمكنك إطعامها ، ورعايتها ، وحتى تعليمها الحيل. ليس الأمر أنني لا أثق بك &#8230; لكني أبقيه مقيدًا ، حسنًا؟<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">مثال من العالم الحقيقي (نوعًا ما)</span></strong></p>
<p>لمثالك التمهيدي ، ستستخدم JSONPlaceholder ، وهو مصدر رائع لبيانات JSON المزيفة لأغراض التدريب.</p>
<p>قم أولاً بإنشاء ملف نصي يسمى scratch.py ​​، أو أي شيء تريده. لا أستطيع حقًا إيقافك.</p>
<p>ستحتاج إلى تقديم طلب واجهة برمجة التطبيقات إلى خدمة JSONPlaceholder ، لذلك ما عليك سوى استخدام حزمة الطلبات للقيام بالأعباء الثقيلة. أضف هذه الواردات في الجزء العلوي من ملفك:<br />
</span></p>
<pre><code><span class="kn">import</span> <span class="nn">json</span>
<span class="kn">import</span> <span class="nn">requests</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الآن ، ستعمل مع قائمة TODOs مثل &#8230; كما تعلم ، إنها طقوس المرور أو أي شيء آخر.</p>
<p>انطلق وقم بتقديم طلب إلى JSONPlaceholder API لنقطة نهاية todos /. إذا لم تكن على دراية بالطلبات ، فهناك بالفعل طريقة json () مفيدة ستؤدي كل العمل نيابة عنك ، ولكن يمكنك التدرب على استخدام مكتبة json لإلغاء تسلسل سمة النص لكائن الاستجابة. يجب أن يبدو مثل هذا:<br />
</span></p>
<pre><code><span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"https://jsonplaceholder.typicode.com/todos"</span><span class="p">)</span>
<span class="n">todos</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لا تعتقد أن هذا يعمل؟ حسنًا ، قم بتشغيل الملف في الوضع التفاعلي واختبره بنفسك. أثناء تواجدك فيه ، تحقق من نوع المهام. إذا كنت تشعر بالمغامرة ، ألق نظرة خاطفة على أول 10 عناصر أو نحو ذلك في القائمة.<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">todos</span> <span class="o">==</span> <span class="n">response</span><span class="o">.</span><span class="n">json</span><span class="p">()</span>
<span class="go">True</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">todos</span><span class="p">)</span>
<span class="go">&lt;class 'list'&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">todos</span><span class="p">[:</span><span class="mi">10</span><span class="p">]</span>
<span class="gp">...</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">انظر ، لن أكذب عليك ، لكنني سعيد لأنك متشكك.<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ما هو الوضع التفاعلي؟ آه ، أعتقد أنك لن تسأل أبدًا! هل تعرف كيف تقفز دائمًا ذهابًا وإيابًا بين المحرر والمحطة؟ حسنًا ، نحن مستخدمي Pythoneers الخادعين نستخدم العلامة التفاعلية -i عند تشغيل البرنامج النصي. هذه خدعة صغيرة رائعة لاختبار الكود لأنه يقوم بتشغيل البرنامج النصي ثم يفتح موجه أوامر تفاعلي مع إمكانية الوصول إلى جميع البيانات من البرنامج النصي!<br />
</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">حسنًا ، حان الوقت لبعض العمل. يمكنك رؤية بنية البيانات من خلال زيارة نقطة النهاية في المتصفح ، ولكن إليك نموذج TODO:<br />
</span></p>
<pre><code><span class="p">{</span>
    <span class="nt">"userId"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
    <span class="nt">"id"</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span>
    <span class="nt">"title"</span><span class="p">:</span> <span class="s2">"delectus aut autem"</span><span class="p">,</span>
    <span class="nt">"completed"</span><span class="p">:</span> <span class="kc">false</span>
<span class="p">}</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هناك عدة مستخدمين ، لكل منهم معرف مستخدم فريد ، ولكل مهمة خاصية مكتملة منطقية. هل يمكنك تحديد المستخدمين الذين أكملوا </span><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">معظم المهام؟</span></p>
<pre><code><span class="c1"># Map of userId to number of complete TODOs for that user</span>
<span class="n">todos_by_user</span> <span class="o">=</span> <span class="p">{}</span>

<span class="c1"># Increment complete TODOs count for each user.</span>
<span class="k">for</span> <span class="n">todo</span> <span class="ow">in</span> <span class="n">todos</span><span class="p">:</span>
    <span class="k">if</span> <span class="n">todo</span><span class="p">[</span><span class="s2">"completed"</span><span class="p">]:</span>
        <span class="k">try</span><span class="p">:</span>
            <span class="c1"># Increment the existing user's count.</span>
            <span class="n">todos_by_user</span><span class="p">[</span><span class="n">todo</span><span class="p">[</span><span class="s2">"userId"</span><span class="p">]]</span> <span class="o">+=</span> <span class="mi">1</span>
        <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
            <span class="c1"># This user has not been seen. Set their count to 1.</span>
            <span class="n">todos_by_user</span><span class="p">[</span><span class="n">todo</span><span class="p">[</span><span class="s2">"userId"</span><span class="p">]]</span> <span class="o">=</span> <span class="mi">1</span>

<span class="c1"># Create a sorted list of (userId, num_complete) pairs.</span>
<span class="n">top_users</span> <span class="o">=</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">todos_by_user</span><span class="o">.</span><span class="n">items</span><span class="p">(),</span> 
                   <span class="n">key</span><span class="o">=</span><span class="k">lambda</span> <span class="n">x</span><span class="p">:</span> <span class="n">x</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">reverse</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>

<span class="c1"># Get the maximum number of complete TODOs.</span>
<span class="n">max_complete</span> <span class="o">=</span> <span class="n">top_users</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span>

<span class="c1"># Create a list of all users who have completed</span>
<span class="c1"># the maximum number of TODOs.</span>
<span class="n">users</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">user</span><span class="p">,</span> <span class="n">num_complete</span> <span class="ow">in</span> <span class="n">top_users</span><span class="p">:</span>
    <span class="k">if</span> <span class="n">num_complete</span> <span class="o">&lt;</span> <span class="n">max_complete</span><span class="p">:</span>
        <span class="k">break</span>
    <span class="n">users</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">user</span><span class="p">))</span>

<span class="n">max_users</span> <span class="o">=</span> <span class="s2">" and "</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">users</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">نعم ، نعم ، التنفيذ أفضل ، ولكن النقطة المهمة هي أنه يمكنك الآن معالجة بيانات JSON ككائن Python عادي!</p>
<p>لا أعرف شيئًا عنك ، ولكن عندما أقوم بتشغيل البرنامج النصي بشكل تفاعلي مرة أخرى ، أحصل على النتائج التالية:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">s</span> <span class="o">=</span> <span class="s2">"s"</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">users</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span> <span class="k">else</span> <span class="s2">""</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"user</span><span class="si">{</span><span class="n">s</span><span class="si">}</span> <span class="si">{</span><span class="n">max_users</span><span class="si">}</span><span class="s2"> completed </span><span class="si">{</span><span class="n">max_complete</span><span class="si">}</span><span class="s2"> TODOs"</span><span class="p">)</span>
<span class="go">users 5 and 10 completed 12 TODOs</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هذا رائع وكل شيء ، لكنك هنا للتعرف على JSON. لمهمتك النهائية ، ستقوم بإنشاء ملف JSON يحتوي على TODOs المكتملة لكل من المستخدمين الذين أكملوا الحد الأقصى لعدد TODO.</p>
<p>كل ما عليك فعله هو تصفية المهام وكتابة القائمة الناتجة إلى ملف. من أجل الأصالة ، يمكنك استدعاء ملف الإخراج filtered_data_file.json. قد توجد طرق يمكنك اتباعها لحل هذا الأمر ، ولكن إليك إحدى الطرق:<br />
</span></p>
<pre><code><span class="c1"># Define a function to filter out completed TODOs </span>
<span class="c1"># of users with max completed TODOS.</span>
<span class="k">def</span> <span class="nf">keep</span><span class="p">(</span><span class="n">todo</span><span class="p">):</span>
    <span class="n">is_complete</span> <span class="o">=</span> <span class="n">todo</span><span class="p">[</span><span class="s2">"completed"</span><span class="p">]</span>
    <span class="n">has_max_count</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">todo</span><span class="p">[</span><span class="s2">"userId"</span><span class="p">])</span> <span class="ow">in</span> <span class="n">users</span>
    <span class="k">return</span> <span class="n">is_complete</span> <span class="ow">and</span> <span class="n">has_max_count</span>

<span class="c1"># Write filtered TODOs to file.</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"filtered_data_file.json"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span> <span class="k">as</span> <span class="n">data_file</span><span class="p">:</span>
    <span class="n">filtered_todos</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">filter</span><span class="p">(</span><span class="n">keep</span><span class="p">,</span> <span class="n">todos</span><span class="p">))</span>
    <span class="n">json</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">filtered_todos</span><span class="p">,</span> <span class="n">data_file</span><span class="p">,</span> <span class="n">indent</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">رائع ، لقد تخلصت من جميع البيانات التي لا تحتاجها وحفظت الأشياء الجيدة في ملف جديد تمامًا! قم بتشغيل البرنامج النصي مرة أخرى وتحقق من filtered_data_file.json للتحقق من نجاح كل شيء. سيكون في نفس الدليل مثل scratch.py ​​عند تشغيله.</p>
<p>الآن بعد أن وصلت إلى هذا الحد ، أراهن أنك تشعر ببعض الأشياء الساخنة ، أليس كذلك؟ لا تكن مغرورًا: التواضع فضيلة. أنا أميل إلى الاتفاق معك رغم ذلك. حتى الآن ، كان الإبحار سلسًا ، ولكن قد ترغب في تثبيت الأبواب لهذه المرحلة الأخيرة من الرحلة.</p>
<p><strong><span style="font-size: 20pt">ترميز وفك ترميز كائنات Python المخصصة</span></strong></p>
<p>ماذا يحدث عندما نحاول إجراء تسلسل لفئة Elf من تطبيق Dungeons &amp; Dragons الذي تعمل عليه؟<br />
</span></p>
<pre><code><span class="k">class</span> <span class="nc">Elf</span><span class="p">:</span>
    <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">level</span><span class="p">,</span> <span class="n">ability_scores</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">level</span> <span class="o">=</span> <span class="n">level</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">ability_scores</span> <span class="o">=</span> <span class="p">{</span>
            <span class="s2">"str"</span><span class="p">:</span> <span class="mi">11</span><span class="p">,</span> <span class="s2">"dex"</span><span class="p">:</span> <span class="mi">12</span><span class="p">,</span> <span class="s2">"con"</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span>
            <span class="s2">"int"</span><span class="p">:</span> <span class="mi">16</span><span class="p">,</span> <span class="s2">"wis"</span><span class="p">:</span> <span class="mi">14</span><span class="p">,</span> <span class="s2">"cha"</span><span class="p">:</span> <span class="mi">13</span>
        <span class="p">}</span> <span class="k">if</span> <span class="n">ability_scores</span> <span class="ow">is</span> <span class="kc">None</span> <span class="k">else</span> <span class="n">ability_scores</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">hp</span> <span class="o">=</span> <span class="mi">10</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">ability_scores</span><span class="p">[</span><span class="s2">"con"</span><span class="p">]</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ليس من المستغرب أن تشتكي Python من أن Elf غير قابل للتسلسل (وهو ما ستعرفه إذا كنت قد حاولت إخبار Elf بخلاف ذلك):<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">elf</span> <span class="o">=</span> <span class="n">Elf</span><span class="p">(</span><span class="n">level</span><span class="o">=</span><span class="mi">4</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">elf</span><span class="p">)</span>
<span class="go">TypeError: Object of type 'Elf' is not JSON serializable</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">على الرغم من أن وحدة json يمكنها التعامل مع معظم أنواع Python المضمنة ، إلا أنها لا تفهم كيفية تشفير أنواع البيانات المخصصة افتراضيًا. يبدو الأمر أشبه بمحاولة وضع مشبك مربّع في ثقب دائري — أنت بحاجة إلى منشار أزيز وإشراف أبوي.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>تبسيط هياكل البيانات</strong></p>
<p>الآن ، السؤال هو كيفية التعامل مع هياكل البيانات الأكثر تعقيدًا. حسنًا ، يمكنك محاولة ترميز JSON وفك تشفيره يدويًا ، ولكن هناك حل أكثر ذكاءً قليلاً سيوفر لك بعض العمل. بدلاً من الانتقال مباشرة من نوع البيانات المخصصة إلى JSON ، يمكنك طرح خطوة وسيطة.</p>
<p>كل ما عليك فعله هو تمثيل بياناتك من حيث الأنواع المضمنة التي يفهمها json بالفعل. بشكل أساسي ، تقوم بترجمة الكائن الأكثر تعقيدًا إلى تمثيل أبسط ، والذي تترجمه وحدة json بعد ذلك إلى JSON. إنها مثل خاصية متعدية في الرياضيات: إذا كانت A = B و B = C ، إذن A = C.</p>
<p>لفهم هذا الأمر ، ستحتاج إلى كائن معقد لتلعب به. يمكنك استخدام أي فئة مخصصة تريدها ، لكن لغة Python بها نوع مضمن يسمى معقد لتمثيل الأرقام المعقدة ، ولا يمكن إجراء تسلسل افتراضيًا. لذلك ، من أجل هذه الأمثلة ، سيكون كائنك المعقد كائنًا معقدًا. مرتبك حتى الآن؟<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">z</span> <span class="o">=</span> <span class="mi">3</span> <span class="o">+</span> <span class="mi">8</span><span class="n">j</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">z</span><span class="p">)</span>
<span class="go">&lt;class 'complex'&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">z</span><span class="p">)</span>
<span class="go">TypeError: Object of type 'complex' is not JSON serializable</span>
</code></pre>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">من أين تأتي الأعداد المركبة؟ كما ترى ، عندما يحب عدد حقيقي ورقم وهمي بعضهما البعض كثيرًا ، فإنهما يجمعان معًا لإنتاج رقم يسمى (بشكل مبرر) معقد.<br />
</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">من الأسئلة الجيدة التي يجب أن تطرحها على نفسك عند العمل مع أنواع مخصصة ما هو الحد الأدنى من المعلومات اللازمة لإعادة إنشاء هذا الكائن؟ في حالة الأعداد المركبة ، ما عليك سوى معرفة الأجزاء الحقيقية والخيالية ، وكلاهما يمكنك الوصول إليه كسمات على الكائن المعقد:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">z</span><span class="o">.</span><span class="n">real</span>
<span class="go">3.0</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">z</span><span class="o">.</span><span class="n">imag</span>
<span class="go">8.0</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يعد تمرير نفس الأرقام إلى مُنشئ معقد كافيًا لإرضاء عامل المقارنة __eq__:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">complex</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mi">8</span><span class="p">)</span> <span class="o">==</span> <span class="n">z</span>
<span class="go">True</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يعد تقسيم أنواع البيانات المخصصة إلى مكوناتها الأساسية أمرًا بالغ الأهمية لكل من عمليات التسلسل وإلغاء التسلسل.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>ترميز أنواع مخصصة</strong></p>
<p>لترجمة كائن مخصص إلى JSON ، كل ما عليك فعله هو توفير وظيفة تشفير للمعامل الافتراضي للطريقة dump (). ستستدعي وحدة json هذه الوظيفة على أي كائنات غير قابلة للتسلسل في الأصل. فيما يلي وظيفة فك تشفير بسيطة يمكنك استخدامها للتدريب:<br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">encode_complex</span><span class="p">(</span><span class="n">z</span><span class="p">):</span>
    <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">z</span><span class="p">,</span> <span class="nb">complex</span><span class="p">):</span>
        <span class="k">return</span> <span class="p">(</span><span class="n">z</span><span class="o">.</span><span class="n">real</span><span class="p">,</span> <span class="n">z</span><span class="o">.</span><span class="n">imag</span><span class="p">)</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">type_name</span> <span class="o">=</span> <span class="n">z</span><span class="o">.</span><span class="vm">__class__</span><span class="o">.</span><span class="vm">__name__</span>
        <span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Object of type '</span><span class="si">{</span><span class="n">type_name</span><span class="si">}</span><span class="s2">' is not JSON serializable"</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ أنه من المتوقع أن تثير خطأ TypeError إذا لم تحصل على نوع الكائن الذي كنت تتوقعه. بهذه الطريقة ، تتجنب إجراء تسلسل غير مقصود لأي من الجان. الآن يمكنك محاولة ترميز العناصر المعقدة بنفسك!<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="mi">9</span> <span class="o">+</span> <span class="mi">5</span><span class="n">j</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">encode_complex</span><span class="p">)</span>
<span class="go">'[9.0, 5.0]'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">elf</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">encode_complex</span><span class="p">)</span>
<span class="go">TypeError: Object of type 'Elf' is not JSON serializable</span>
</code></pre>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لماذا قمنا بترميز العدد المركب على هيئة tuple؟ سؤال رائع! لم يكن هذا بالتأكيد هو الخيار الوحيد ، كما أنه ليس بالضرورة الخيار الأفضل. في الواقع ، لن يكون هذا تمثيلًا جيدًا جدًا إذا أردت في أي وقت فك تشفير الكائن لاحقًا ، كما سترى قريبًا.<br />
</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الطريقة الأخرى الشائعة هي تصنيف JSONEncoder القياسي وتجاوز طريقة () الافتراضية الخاصة به:<br />
</span></p>
<pre><code><span class="k">class</span> <span class="nc">ComplexEncoder</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">JSONEncoder</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">default</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">z</span><span class="p">):</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">z</span><span class="p">,</span> <span class="nb">complex</span><span class="p">):</span>
            <span class="k">return</span> <span class="p">(</span><span class="n">z</span><span class="o">.</span><span class="n">real</span><span class="p">,</span> <span class="n">z</span><span class="o">.</span><span class="n">imag</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">default</span><span class="p">(</span><span class="n">z</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بدلاً من رفع TypeError بنفسك ، يمكنك ببساطة السماح للفئة الأساسية بمعالجتها. يمكنك استخدام هذا إما مباشرة في طريقة dump () عبر المعامل cls أو عن طريق إنشاء مثيل من المشفر واستدعاء طريقة encode ():<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="mi">2</span> <span class="o">+</span> <span class="mi">5</span><span class="n">j</span><span class="p">,</span> <span class="bp">cls</span><span class="o">=</span><span class="n">ComplexEncoder</span><span class="p">)</span>
<span class="go">'[2.0, 5.0]'</span>

<span class="gp">&gt;&gt;&gt; </span><span class="n">encoder</span> <span class="o">=</span> <span class="n">ComplexEncoder</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">encoder</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="mi">3</span> <span class="o">+</span> <span class="mi">6</span><span class="n">j</span><span class="p">)</span>
<span class="go">'[3.0, 6.0]'</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>أنواع مخصصة فك التشفير</strong></p>
<p>في حين أن الأجزاء الحقيقية والخيالية للعدد المركب ضرورية للغاية ، إلا أنها في الواقع ليست كافية تمامًا لإعادة إنشاء الكائن. هذا ما يحدث عندما تحاول ترميز رقم معقد باستخدام ComplexEncoder ثم فك ترميز النتيجة:</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">complex_json</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="mi">4</span> <span class="o">+</span> <span class="mi">17</span><span class="n">j</span><span class="p">,</span> <span class="bp">cls</span><span class="o">=</span><span class="n">ComplexEncoder</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">complex_json</span><span class="p">)</span>
<span class="go">[4.0, 17.0]</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كل ما تحصل عليه هو قائمة ، وعليك تمرير القيم إلى مُنشئ معقد إذا أردت هذا الكائن المعقد مرة أخرى. أذكر مناقشتنا حول النقل الآني. ما ينقص هو البيانات الوصفية ، أو المعلومات حول نوع البيانات التي تقوم بتشفيرها.</p>
<p>أفترض أن السؤال الذي يجب أن تطرحه على نفسك حقًا هو ما هو الحد الأدنى من المعلومات الضرورية والكافية لإعادة إنشاء هذا الكائن؟</p>
<p>تتوقع وحدة json أن يتم التعبير عن جميع الأنواع المخصصة ككائنات في معيار JSON. للتنوع ، يمكنك إنشاء ملف JSON هذه المرة يسمى complex_data.json وإضافة الكائن التالي الذي يمثل رقمًا معقدًا:<br />
</span></p>
<pre><code><span class="p">{</span>
    <span class="nt">"__complex__"</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
    <span class="nt">"real"</span><span class="p">:</span> <span class="mi">42</span><span class="p">,</span>
    <span class="nt">"imag"</span><span class="p">:</span> <span class="mi">36</span>
<span class="p">}</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">رؤية الشيء الذكي؟ هذا المفتاح &#8220;__complex__&#8221; هو البيانات الوصفية التي تحدثنا عنها للتو. لا يهم حقًا ما هي القيمة المرتبطة. لجعل هذا الاختراق الصغير يعمل ، كل ما عليك فعله هو التحقق من وجود المفتاح:<br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">decode_complex</span><span class="p">(</span><span class="n">dct</span><span class="p">):</span>
    <span class="k">if</span> <span class="s2">"__complex__"</span> <span class="ow">in</span> <span class="n">dct</span><span class="p">:</span>
        <span class="k">return</span> <span class="nb">complex</span><span class="p">(</span><span class="n">dct</span><span class="p">[</span><span class="s2">"real"</span><span class="p">],</span> <span class="n">dct</span><span class="p">[</span><span class="s2">"imag"</span><span class="p">])</span>
    <span class="k">return</span> <span class="n">dct</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا لم يكن &#8220;__complex__&#8221; موجودًا في القاموس ، يمكنك فقط إرجاع الكائن والسماح لوحدة فك الترميز الافتراضية بالتعامل معه.</p>
<p>في كل مرة تحاول طريقة load () تحليل كائن ما ، يتم منحك الفرصة للتوسط قبل أن تشغل وحدة فك التشفير الافتراضية طريقها مع البيانات. يمكنك القيام بذلك عن طريق تمرير وظيفة فك التشفير الخاصة بك إلى معلمة object_hook.</p>
<p>العب الآن نفس نوع اللعبة كما كان من قبل:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"complex_data.json"</span><span class="p">)</span> <span class="k">as</span> <span class="n">complex_data</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">data</span> <span class="o">=</span> <span class="n">complex_data</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="gp">... </span>    <span class="n">z</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">object_hook</span><span class="o">=</span><span class="n">decode_complex</span><span class="p">)</span>
<span class="gp">... </span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">z</span><span class="p">)</span>
<span class="go">&lt;class 'complex'&gt;</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في حين أن object_hook قد يبدو وكأنه المقابل للمعامل الافتراضي لطريقة dump () ، فإن القياس يبدأ وينتهي هناك.</p>
<p>هذا لا يعمل مع كائن واحد فقط. جرب وضع قائمة الأعداد المركبة هذه في complex_data.json وتشغيل البرنامج النصي مرة أخرى:<br />
</span></p>
<pre><code><span class="p">[</span>
  <span class="p">{</span>
    <span class="nt">"__complex__"</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span>
    <span class="nt">"real"</span><span class="p">:</span><span class="mi">42</span><span class="p">,</span>
    <span class="nt">"imag"</span><span class="p">:</span><span class="mi">36</span>
  <span class="p">},</span>
  <span class="p">{</span>
    <span class="nt">"__complex__"</span><span class="p">:</span><span class="kc">true</span><span class="p">,</span>
    <span class="nt">"real"</span><span class="p">:</span><span class="mi">64</span><span class="p">,</span>
    <span class="nt">"imag"</span><span class="p">:</span><span class="mi">11</span>
  <span class="p">}</span>
<span class="p">]</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا سارت الأمور على ما يرام ، فستحصل على قائمة بالكائنات المعقدة:<br />
</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"complex_data.json"</span><span class="p">)</span> <span class="k">as</span> <span class="n">complex_data</span><span class="p">:</span>
<span class="gp">... </span>    <span class="n">data</span> <span class="o">=</span> <span class="n">complex_data</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
<span class="gp">... </span>    <span class="n">numbers</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">object_hook</span><span class="o">=</span><span class="n">decode_complex</span><span class="p">)</span>
<span class="gp">... </span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">numbers</span>
<span class="go">[(42+36j), (64+11j)]</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكنك أيضًا تجربة التصنيف الفرعي JSONDecoder وتجاوز object_hook ، ولكن من الأفضل التمسك بالحل خفيف الوزن كلما أمكن ذلك.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">كله تمام!</span></strong></p>
<p>تهانينا ، يمكنك الآن استخدام القوة الجبارة لـ JSON لجميع احتياجات Python الشائنة.</p>
<p>في حين أن الأمثلة التي عملت معها هنا هي بالتأكيد مفتعلة ومفرطة في التبسيط ، فإنها توضح سير عمل يمكنك تطبيقه على مهام أكثر عمومية:<br />
</span></p>
<ol>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">قم باستيراد حزمة json.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">اقرأ البيانات مع load () أو loads ().<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">معالجة البيانات.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">اكتب البيانات المعدلة مع تفريغ () أو تفريغ ().<br />
</span></li>
</ol>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يعتمد ما تفعله ببياناتك بمجرد تحميلها في الذاكرة على حالة الاستخدام الخاصة بك. بشكل عام ، سيكون هدفك هو جمع البيانات من المصدر ، واستخراج المعلومات المفيدة ، وتمرير هذه المعلومات أو الاحتفاظ بسجل لها.</p>
<p>لقد قمت اليوم برحلة: لقد التقطت بعض JSON البرية وقمت بترويضها ، وقمت بالعودة في الوقت المناسب لتناول العشاء! كمكافأة إضافية ، فإن تعلم حزمة json سيجعل تعلم المخلل والتنظيم أمرًا سريعًا.</p>
<p>حظًا سعيدًا في كل مساعيك البايثونية المستقبلية!</span></p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d8%a7%d9%84%d8%b9%d9%85%d9%84-%d9%85%d8%b9-%d8%a8%d9%8a%d8%a7%d9%86%d8%a7%d8%aa-json-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/">العمل مع بيانات JSON في بايثون</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://arabdars.com/%d8%a7%d9%84%d8%b9%d9%85%d9%84-%d9%85%d8%b9-%d8%a8%d9%8a%d8%a7%d9%86%d8%a7%d8%aa-json-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>تصحيح أخطاء Python باستخدام Pdb</title>
		<link>https://arabdars.com/%d8%aa%d8%b5%d8%ad%d9%8a%d8%ad-%d8%a3%d8%ae%d8%b7%d8%a7%d8%a1-python-%d8%a8%d8%a7%d8%b3%d8%aa%d8%ae%d8%af%d8%a7%d9%85-pdb/</link>
					<comments>https://arabdars.com/%d8%aa%d8%b5%d8%ad%d9%8a%d8%ad-%d8%a3%d8%ae%d8%b7%d8%a7%d8%a1-python-%d8%a8%d8%a7%d8%b3%d8%aa%d8%ae%d8%af%d8%a7%d9%85-pdb/#respond</comments>
		
		<dc:creator><![CDATA[Reyhane]]></dc:creator>
		<pubDate>Thu, 17 Sep 2020 15:34:29 +0000</pubDate>
				<category><![CDATA[الماتلاب Matlab]]></category>
		<guid isPermaLink="false">https://arabdars.com/?p=1619</guid>

					<description><![CDATA[<p>جدول المحتويات الشروع في العمل: طباعة قيمة متغير تعبيرات الطباعة يخطو من خلال التعليمات البرمجية إدراج رمز المصدر استخدام نقاط التوقف استمرار التنفيذ عرض التعبيرات معرف المتصل بيثون أوامر pdb الأساسية تصحيح أخطاء بايثون باستخدام PDB: الخاتمة يمكن أن تكون تطبيقات تصحيح الأخطاء أحيانًا نشاطًا غير مرغوب فيه. أنت مشغول بالعمل في ظل أزمة زمنية [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d8%aa%d8%b5%d8%ad%d9%8a%d8%ad-%d8%a3%d8%ae%d8%b7%d8%a7%d8%a1-python-%d8%a8%d8%a7%d8%b3%d8%aa%d8%ae%d8%af%d8%a7%d9%85-pdb/">تصحيح أخطاء Python باستخدام Pdb</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">جدول المحتويات</span></strong><br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الشروع في العمل: طباعة قيمة متغير<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تعبيرات الطباعة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يخطو من خلال التعليمات البرمجية<br />
إدراج رمز المصدر<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">استخدام نقاط التوقف<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">استمرار التنفيذ<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عرض التعبيرات<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">معرف المتصل بيثون<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">أوامر pdb الأساسية<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تصحيح أخطاء بايثون باستخدام PDB: الخاتمة<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن أن تكون تطبيقات تصحيح الأخطاء أحيانًا نشاطًا غير مرغوب فيه. أنت مشغول بالعمل في ظل أزمة زمنية وتريدها فقط أن تعمل. ومع ذلك ، في أوقات أخرى ، قد تتعلم ميزة لغة جديدة أو تجرب نهجًا جديدًا وتريد أن تفهم بشكل أعمق كيف يعمل شيء ما.</p>
<p>بغض النظر عن الموقف ، يعد تصحيح الأخطاء أمرًا ضروريًا ، لذلك من الجيد أن تكون مرتاحًا عند العمل في مصحح أخطاء. في هذا البرنامج التعليمي ، سأوضح لك أساسيات استخدام pdb ، مصحح أخطاء شفرة المصدر التفاعلي في Python.</p>
<p>سأوجهك خلال بعض الاستخدامات الشائعة لـ pdb. قد ترغب في وضع إشارة مرجعية على هذا البرنامج التعليمي للرجوع إليه سريعًا لاحقًا عندما تحتاج إليه حقًا. pdb ومصححات الأخطاء الأخرى هي أدوات لا غنى عنها. عندما تحتاج إلى مصحح أخطاء ، فليس هناك بديل. أنت حقا بحاجة إليه.</p>
<p>بنهاية هذا البرنامج التعليمي ، ستعرف كيفية استخدام مصحح الأخطاء لمعرفة حالة أي متغير في تطبيقك. ستتمكن أيضًا من إيقاف واستئناف تدفق تنفيذ تطبيقك في أي لحظة ، حتى تتمكن من معرفة كيفية تأثير كل سطر من التعليمات البرمجية على حالته الداخلية.</p>
<p>يعد هذا أمرًا رائعًا لتتبع الأخطاء التي يصعب العثور عليها ويسمح لك بإصلاح التعليمات البرمجية الخاطئة بسرعة وموثوقية أكبر. في بعض الأحيان ، يمكن أن يكون التنقل خلال التعليمات البرمجية في pdb ورؤية كيف يمكن أن يكون تغيير القيم أمرًا مثيرًا للانتباه ويؤدي إلى لحظات &#8220;aha&#8221; ، جنبًا إلى جنب مع &#8220;راحة اليد&#8221;.</p>
<p>يعد pdb جزءًا من مكتبة Python القياسية ، لذا فهو موجود دائمًا ومتاح للاستخدام. يمكن أن يكون هذا منقذًا للحياة إذا كنت بحاجة إلى تصحيح أخطاء التعليمات البرمجية في بيئة لا يمكنك فيها الوصول إلى مصحح أخطاء واجهة المستخدم الرسومية الذي تعرفه.</p>
<p>يستخدم رمز المثال في هذا البرنامج التعليمي Python 3.6. يمكنك العثور على الكود المصدري لهذه الأمثلة على GitHub.</p>
<p>في نهاية هذا البرنامج التعليمي ، يوجد مرجع سريع لأوامر pdb الأساسية.</p>
<p>هناك أيضًا مرجع أوامر pdb قابل للطباعة يمكنك استخدامه كورقة غش أثناء تصحيح الأخطاء:</p>
<p><strong><span style="font-size: 20pt">الشروع في العمل: طباعة قيمة متغير</span></strong></p>
<p>في هذا المثال الأول ، سننظر في استخدام pdb في أبسط صوره: التحقق من قيمة المتغير.</p>
<p>أدخل الكود التالي في المكان الذي تريد اقتحام مصحح الأخطاء فيه:</span></p>
<pre><code><span class="kn">import</span> <span class="nn">pdb</span><span class="p">;</span> <span class="n">pdb</span><span class="o">.</span><span class="n">set_trace</span><span class="p">()</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عندما يتم تنفيذ السطر أعلاه ، تتوقف Python وتنتظر حتى تخبرها بما يجب فعله بعد ذلك. سترى مطالبة (Pdb). هذا يعني أنك الآن متوقف مؤقتًا في مصحح الأخطاء التفاعلي ويمكنك إدخال أمر.</p>
<p>بدءًا من Python 3.7 ، هناك طريقة أخرى للدخول إلى مصحح الأخطاء. يصف PEP 553 نقطة توقف الوظيفة المضمنة () ، مما يجعل إدخال مصحح الأخطاء أمرًا سهلاً ومتسقًا:<br />
</span></p>
<pre><code><span class="n">breakpoint</span><span class="p">()</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بشكل افتراضي ، ستقوم نقطة التوقف () باستيراد pdb واستدعاء pdb.set_trace () ، كما هو موضح أعلاه. ومع ذلك ، يعد استخدام نقطة التوقف () أكثر مرونة ويسمح لك بالتحكم في سلوك تصحيح الأخطاء عبر واجهة برمجة التطبيقات واستخدام متغير البيئة PYTHONBREAKPOINT. على سبيل المثال ، سيؤدي تعيين PYTHONBREAKPOINT = 0 في بيئتك إلى تعطيل نقطة التوقف () تمامًا ، وبالتالي تعطيل تصحيح الأخطاء. إذا كنت تستخدم Python 3.7 أو إصدارًا أحدث ، فأنا أشجعك على استخدام نقطة التوقف () بدلاً من pdb.set_trace ().</p>
<p>يمكنك أيضًا اقتحام مصحح الأخطاء ، دون تعديل المصدر واستخدام pdb.set_trace () أو نقطة التوقف () ، عن طريق تشغيل Python مباشرةً من سطر الأوامر وتمرير الخيار -m pdb. إذا كان التطبيق الخاص بك يقبل وسيطات سطر الأوامر ، فمررها كما تفعل عادةً بعد اسم الملف. فمثلا:<br />
</span></p>
<pre><code><span class="gp">$</span> python3 -m pdb app.py arg1 arg2</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هناك الكثير من أوامر pdb المتاحة. في نهاية هذا البرنامج التعليمي ، توجد قائمة بأوامر pdb الأساسية. في الوقت الحالي ، دعنا نستخدم الأمر p لطباعة قيمة المتغير. أدخل p Vari_name في موجه (Pdb) لطباعة قيمته.</p>
<p>دعونا نلقي نظرة على المثال. إليك مصدر example1.py:<br />
</span></p>
<pre><code><span class="ch">#!/usr/bin/env python3</span>

<span class="n">filename</span> <span class="o">=</span> <span class="vm">__file__</span>
<span class="kn">import</span> <span class="nn">pdb</span><span class="p">;</span> <span class="n">pdb</span><span class="o">.</span><span class="n">set_trace</span><span class="p">()</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'path = </span><span class="si">{</span><span class="n">filename</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا قمت بتشغيل هذا من shell الخاص بك ، يجب أن تحصل على الإخراج التالي:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example1.py 
<span class="gp">&gt;</span> /code/example1.py<span class="o">(</span><span class="m">5</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; print(f'path = {filename}')</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا كنت تواجه مشكلة في الحصول على الأمثلة أو التعليمات البرمجية الخاصة بك لتشغيلها من سطر الأوامر ، فاقرأ كيف أقوم بعمل أوامر سطر الأوامر الخاصة بي باستخدام Python؟ إذا كنت تستخدم نظام Windows ، فتحقق من الأسئلة الشائعة حول Python Windows.</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">أدخل الآن اسم الملف p. يجب أن ترى:</span></p>
<pre><code><span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p filename</span>
<span class="go">'./example1.py'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">نظرًا لأنك تعمل في shell وتستخدم CLI (واجهة سطر الأوامر) ، انتبه إلى الأحرف والتنسيق. سيعطونك السياق الذي تحتاجه:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">&gt; يبدأ السطر الأول ويخبرك بالملف المصدر الذي تستخدمه. بعد اسم الملف ، يوجد رقم السطر الحالي بين قوسين. التالي هو اسم الوظيفة. في هذا المثال ، نظرًا لأننا لم نتوقف مؤقتًا داخل دالة وعلى مستوى الوحدة ، نرى &lt;module&gt; ().<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">-&gt; يبدأ السطر الثاني وهو سطر المصدر الحالي حيث يتم إيقاف Python مؤقتًا. لم يتم تنفيذ هذا الخط حتى الآن. في هذا المثال ، هذا هو السطر 5 في example1.py ، من&gt; السطر أعلاه.</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">(Pdb) هو موجه pdb. إنها تنتظر أمرًا.</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">استخدم الأمر q لإنهاء التصحيح والخروج.</p>
<p><strong><span style="font-size: 20pt">تعبيرات الطباعة</span></strong></span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عند استخدام الأمر print p ، فأنت تقوم بتمرير تعبير ليتم تقييمه بواسطة Python. إذا قمت بتمرير اسم متغير ، فإن pdb يطبع قيمته الحالية. ومع ذلك ، يمكنك فعل الكثير للتحقق من حالة التطبيق قيد التشغيل.</p>
<p>في هذا المثال ، يتم استدعاء الدالة get_path (). لفحص ما يحدث في هذه الوظيفة ، قمت بإدخال استدعاء إلى pdb.set_trace () لإيقاف التنفيذ مؤقتًا قبل أن يعود:<br />
</span></p>
<pre><code><span class="ch">#!/usr/bin/env python3</span>

<span class="kn">import</span> <span class="nn">os</span>


<span class="k">def</span> <span class="nf">get_path</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
    <span class="sd">"""Return file's path or empty string if no path."""</span>
    <span class="n">head</span><span class="p">,</span> <span class="n">tail</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
    <span class="kn">import</span> <span class="nn">pdb</span><span class="p">;</span> <span class="n">pdb</span><span class="o">.</span><span class="n">set_trace</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">head</span>


<span class="n">filename</span> <span class="o">=</span> <span class="vm">__file__</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'path = </span><span class="si">{</span><span class="n">get_path</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا قمت بتشغيل هذا من قوقعتك ، فيجب أن تحصل على الإخراج:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example2.py 
<span class="gp">&gt;</span> /code/example2.py<span class="o">(</span><span class="m">10</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">اين نحن؟<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">&gt;: نحن في الملف المصدر example2.py في السطر 10 في الوظيفة get_path (). هذا هو الإطار المرجعي الذي سيستخدمه الأمر p لحل أسماء المتغيرات ، أي النطاق أو السياق الحالي.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">-&gt;: توقف التنفيذ عند رأس العودة. لم يتم تنفيذ هذا الخط حتى الآن. هذا هو السطر 10 في example2.py في الوظيفة get_path () ، من&gt; السطر أعلاه.<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">دعنا نطبع بعض التعبيرات لإلقاء نظرة على الحالة الحالية للتطبيق. أستخدم الأمر ll (القائمة الطويلة) مبدئيًا لسرد مصدر الوظيفة:<br />
</span></p>
<pre><code><span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">ll</span>
<span class="go">  6     def get_path(filename):</span>
<span class="go">  7         """Return file's path or empty string if no path."""</span>
<span class="go">  8         head, tail = os.path.split(filename)</span>
<span class="go">  9         import pdb; pdb.set_trace()</span>
<span class="go"> 10  -&gt;     return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p filename</span>
<span class="go">'./example2.py'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p head, tail</span>
<span class="gp gp-VirtualEnv">('.', 'example2.py')</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p 'filename: ' + filename</span>
<span class="go">'filename: ./example2.py'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p get_path</span>
<span class="go">&lt;function get_path at 0x100760e18&gt;</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p getattr(get_path, '__doc__')</span>
<span class="go">"Return file's path or empty string if no path."</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p [os.path.split(p)[1] for p in os.path.sys.path]</span>
<span class="go">['pdb-basics', 'python36.zip', 'python3.6', 'lib-dynload', 'site-packages']</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكنك تمرير أي تعبير Python صالح إلى p للتقييم.</p>
<p>هذا مفيد بشكل خاص عند تصحيح الأخطاء وترغب في اختبار تطبيق بديل مباشرة في التطبيق في وقت التشغيل.</p>
<p>يمكنك أيضًا استخدام الأمر pp (طباعة جميلة) لطباعة التعبيرات. هذا مفيد إذا كنت تريد طباعة متغير أو تعبير بكمية كبيرة من الإخراج ، على سبيل المثال القوائم والقواميس. تحافظ الطباعة الجيدة على الكائنات في سطر واحد إذا كان ذلك ممكنًا أو تقسمها إلى أسطر متعددة إذا لم تتناسب مع العرض المسموح به.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span style="font-size: 20pt"><strong>يخطو من خلال التعليمات البرمجية</strong></span></p>
<p>هناك أمران يمكنك استخدامهما للتنقل عبر التعليمات البرمجية عند تصحيح الأخطاء:<br />
وصف الأمر<br />
n (التالي) تابع التنفيذ حتى يتم الوصول إلى السطر التالي في الوظيفة الحالية أو يعود.<br />
s (الخطوة) قم بتنفيذ السطر الحالي وتوقف عند أول مناسبة ممكنة (إما في وظيفة تسمى أو في الوظيفة الحالية).<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هناك أمر ثالث يسمى unt (حتى). إنه مرتبط بـ n (التالي). سنلقي نظرة عليها لاحقًا في هذا البرنامج التعليمي في قسم التنفيذ المستمر.</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الفرق بين n (التالي) و s (الخطوة) حيث يتوقف pdb.</p>
<p>استخدم n (التالي) لمواصلة التنفيذ حتى السطر التالي والبقاء ضمن الوظيفة الحالية ، أي عدم التوقف في دالة أجنبية إذا تم استدعاء أحدها. فكر في الخطوة التالية على أنها &#8220;البقاء محليًا&#8221; أو &#8220;الخطوة التالية&#8221;.</p>
<p>استخدم s (الخطوة) لتنفيذ السطر الحالي والتوقف في وظيفة خارجية إذا تم استدعاء أحدها. فكر في الخطوة على أنها &#8220;خطوة إلى&#8221;. إذا تم إيقاف التنفيذ في وظيفة أخرى ، فسيتم طباعة &#8211; Call -.</p>
<p>سيتوقف كل من n و s عن التنفيذ عند الوصول إلى نهاية الوظيفة الحالية والطباعة &#8211;Return &#8211; جنبًا إلى جنب مع القيمة المعادة في نهاية السطر التالي بعد -&gt;.</p>
<p>دعونا نلقي نظرة على مثال باستخدام كلا الأمرين. إليك مصدر example3.py:<br />
</span></p>
<pre><code><span class="ch">#!/usr/bin/env python3</span>

<span class="kn">import</span> <span class="nn">os</span>


<span class="k">def</span> <span class="nf">get_path</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
    <span class="sd">"""Return file's path or empty string if no path."""</span>
    <span class="n">head</span><span class="p">,</span> <span class="n">tail</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">head</span>


<span class="n">filename</span> <span class="o">=</span> <span class="vm">__file__</span>
<span class="kn">import</span> <span class="nn">pdb</span><span class="p">;</span> <span class="n">pdb</span><span class="o">.</span><span class="n">set_trace</span><span class="p">()</span>
<span class="n">filename_path</span> <span class="o">=</span> <span class="n">get_path</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'path = </span><span class="si">{</span><span class="n">filename_path</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا قمت بتشغيل هذا من shell الخاص بك وأدخلت n ، يجب أن تحصل على الإخراج:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example3.py 
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">14</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; filename_path = get_path(filename)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">n</span>
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">15</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; print(f'path = {filename_path}')</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">مع n (التالي) ، توقفنا عند السطر 15 ، السطر التالي. &#8220;بقينا محليين&#8221; في &lt;module&gt; () و &#8220;تخطينا&#8221; المكالمة لـ get_path (). الوظيفة هي &lt;module&gt; () نظرًا لأننا حاليًا في مستوى الوحدة ولم نتوقف مؤقتًا داخل وظيفة أخرى.</p>
<p>دعونا نجرب ما يلي:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example3.py 
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">14</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; filename_path = get_path(filename)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">s</span>
<span class="go">--Call--</span>
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">6</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; def get_path(filename):</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">باستخدام s (الخطوة) ، توقفنا عند السطر 6 في الوظيفة get_path () حيث تم استدعاؤها في السطر 14. لاحظ السطر &#8211; Call &#8211; بعد الأمر s.</p>
<p>بشكل ملائم ، يتذكر pdb آخر أمر لك. إذا كنت تتنقل عبر الكثير من التعليمات البرمجية ، يمكنك فقط الضغط على Enter لتكرار الأمر الأخير.</p>
<p>يوجد أدناه مثال على استخدام كل من s و n للتنقل عبر الكود. أقوم بإدخال s في البداية لأنني أريد &#8220;الدخول إلى&#8221; الوظيفة get_path () والتوقف. ثم أدخل n مرة واحدة &#8220;للبقاء محليًا&#8221; أو &#8220;تخطي&#8221; أي استدعاءات وظيفية أخرى واضغط فقط على Enter لتكرار الأمر n حتى أصل إلى آخر سطر مصدر.<br />
</span></p>
<pre><code><span class="gp">$</span> ./example3.py 
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">14</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; filename_path = get_path(filename)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">s</span>
<span class="go">--Call--</span>
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">6</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; def get_path(filename):</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">n</span>
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">8</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; head, tail = os.path.split(filename)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> 
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">9</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> 
<span class="go">--Return--</span>
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">9</span><span class="o">)</span>get_path<span class="o">()</span>-&gt;<span class="s1">'.'</span>
<span class="go">-&gt; return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> 
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">15</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; print(f'path = {filename_path}')</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> 
<span class="go">path = .</span>
<span class="go">--Return--</span>
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">15</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>-&gt;None
<span class="go">-&gt; print(f'path = {filename_path}')</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ السطور &#8211; Call &#8211; and &#8211;Return -. هذا هو pdb الذي يتيح لك معرفة سبب إيقاف الإعدام. n (التالي) و s (الخطوة) ستتوقف قبل أن تعود الدالة. لهذا السبب ترى سطور &#8220;العودة&#8221; أعلاه.</p>
<p>لاحظ أيضًا -&gt; &#8220;.&#8221; في نهاية السطر بعد أول &#8211; رجوع &#8211; أعلاه:<br />
</span></p>
<pre><code><span class="go">--Return--</span>
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">9</span><span class="o">)</span>get_path<span class="o">()</span>-&gt;<span class="s1">'.'</span>
<span class="go">-&gt; return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عندما يتوقف pdb في نهاية دالة قبل أن تعود ، فإنه يطبع أيضًا قيمة الإرجاع لك. في هذا المثال هو &#8220;.&#8221;.</p>
<p><strong>إدراج رمز المصدر</strong></p>
<p>لا تنس الأمر ll (القائمة الطويلة: سرد شفرة المصدر بالكامل للوظيفة أو الإطار الحالي). إنه مفيد حقًا عندما تتخطى رمزًا غير مألوف أو تريد فقط رؤية الوظيفة الكاملة للسياق.</p>
<p>هذا مثال:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example3.py 
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">14</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; filename_path = get_path(filename)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">s</span>
<span class="go">--Call--</span>
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">6</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; def get_path(filename):</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">ll</span>
<span class="go">  6  -&gt; def get_path(filename):</span>
<span class="go">  7         """Return file's path or empty string if no path."""</span>
<span class="go">  8         head, tail = os.path.split(filename)</span>
<span class="go">  9         return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لرؤية مقتطف أقصر من التعليمات البرمجية ، استخدم الأمر l (قائمة). بدون وسيطات ، سيتم طباعة 11 سطرًا حول السطر الحالي أو متابعة القائمة السابقة. مرر الحجة. لإدراج 11 سطرًا دائمًا حول السطر الحالي: l.<br />
</span></p>
<pre><code><span class="gp">$</span> ./example3.py 
<span class="gp">&gt;</span> /code/example3.py<span class="o">(</span><span class="m">14</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; filename_path = get_path(filename)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">l</span>
<span class="go">  9         return head</span>
<span class="go"> 10     </span>
<span class="go"> 11     </span>
<span class="go"> 12     filename = __file__</span>
<span class="go"> 13     import pdb; pdb.set_trace()</span>
<span class="go"> 14  -&gt; filename_path = get_path(filename)</span>
<span class="go"> 15     print(f'path = {filename_path}')</span>
<span class="go">[EOF]</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">l</span>
<span class="go">[EOF]</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">l .</span>
<span class="go">  9         return head</span>
<span class="go"> 10     </span>
<span class="go"> 11     </span>
<span class="go"> 12     filename = __file__</span>
<span class="go"> 13     import pdb; pdb.set_trace()</span>
<span class="go"> 14  -&gt; filename_path = get_path(filename)</span>
<span class="go"> 15     print(f'path = {filename_path}')</span>
<span class="go">[EOF]</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">استخدام نقاط التوقف</span></strong></p>
<p>تعتبر نقاط التوقف مريحة للغاية ويمكن أن توفر لك الكثير من الوقت. بدلاً من المرور عبر عشرات الأسطر التي لا تهتم بها ، قم ببساطة بإنشاء نقطة توقف حيث تريد التحقق منها. اختياريًا ، يمكنك أيضًا إخبار pdb بالكسر فقط عندما يكون شرط معين صحيحًا.</p>
<p>استخدم الأمر ب (فاصل) لتعيين نقطة توقف. يمكنك تحديد رقم سطر أو اسم وظيفة حيث تم إيقاف التنفيذ.</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">صيغة الاستراحة هي:<br />
</span></p>
<pre><code><span class="go">b(reak) [ ([filename:]lineno | function) [, condition] ]</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا لم يتم تحديد filename: قبل lineno رقم السطر ، فسيتم استخدام ملف المصدر الحالي.</p>
<p>لاحظ الوسيطة الثانية الاختيارية لـ b: condition. هذا قوي جدا. تخيل موقفًا تريد كسره فقط في حالة وجود حالة معينة. إذا قمت بتمرير تعبير Python باعتباره الوسيطة الثانية ، فسوف ينكسر pdb عندما يكون التعبير صحيحًا. سنفعل هذا في مثال أدناه.</p>
<p>في هذا المثال ، توجد وحدة الأداة المساعدة util.py. لنقم بتعيين نقطة توقف لإيقاف التنفيذ في دالة get_path ().</p>
<p>في ما يلي مصدر النص الرئيسي example4.py:<br />
</span></p>
<pre><code><span class="ch">#!/usr/bin/env python3</span>

<span class="kn">import</span> <span class="nn">util</span>

<span class="n">filename</span> <span class="o">=</span> <span class="vm">__file__</span>
<span class="kn">import</span> <span class="nn">pdb</span><span class="p">;</span> <span class="n">pdb</span><span class="o">.</span><span class="n">set_trace</span><span class="p">()</span>
<span class="n">filename_path</span> <span class="o">=</span> <span class="n">util</span><span class="o">.</span><span class="n">get_path</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'path = </span><span class="si">{</span><span class="n">filename_path</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إليك مصدر وحدة الأداة المساعدة util.py:<br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">get_path</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
    <span class="sd">"""Return file's path or empty string if no path."""</span>
    <span class="kn">import</span> <span class="nn">os</span>
    <span class="n">head</span><span class="p">,</span> <span class="n">tail</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">head</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">أولاً ، لنقم بتعيين نقطة توقف باستخدام اسم ملف المصدر ورقم السطر:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example4.py 
<span class="gp">&gt;</span> /code/example4.py<span class="o">(</span><span class="m">7</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; filename_path = util.get_path(filename)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">b util:5</span>
<span class="go">Breakpoint 1 at /code/util.py:5</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">c</span>
<span class="gp">&gt;</span> /code/util.py<span class="o">(</span><span class="m">5</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p filename, head, tail</span>
<span class="gp gp-VirtualEnv">('./example4.py', '.', 'example4.py')</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يستمر الأمر c (متابعة) في التنفيذ حتى يتم العثور على نقطة توقف.</p>
<p>بعد ذلك ، دعنا نضبط نقطة توقف باستخدام اسم الوظيفة:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example4.py 
<span class="gp">&gt;</span> /code/example4.py<span class="o">(</span><span class="m">7</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; filename_path = util.get_path(filename)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">b util.get_path</span>
<span class="go">Breakpoint 1 at /code/util.py:1</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">c</span>
<span class="gp">&gt;</span> /code/util.py<span class="o">(</span><span class="m">3</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; import os</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p filename</span>
<span class="go">'./example4.py'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">أدخل b بدون وسيطات لعرض قائمة بجميع نقاط التوقف:<br />
</span></p>
<pre><code><span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">b</span>
<span class="go">Num Type         Disp Enb   Where</span>
<span class="go">1   breakpoint   keep yes   at /code/util.py:1</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكنك تعطيل وإعادة تمكين نقاط التوقف باستخدام الأمر تعطيل bpnumber وتمكين bpnumber. bpnumber هو رقم نقطة التوقف من العمود الأول لقائمة نقاط التوقف Num. لاحظ تغير قيمة عمود Enb:<br />
</span></p>
<pre><code><span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">disable 1</span>
<span class="go">Disabled breakpoint 1 at /code/util.py:1</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">b</span>
<span class="go">Num Type         Disp Enb   Where</span>
<span class="go">1   breakpoint   keep no    at /code/util.py:1</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">enable 1</span>
<span class="go">Enabled breakpoint 1 at /code/util.py:1</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">b</span>
<span class="go">Num Type         Disp Enb   Where</span>
<span class="go">1   breakpoint   keep yes   at /code/util.py:1</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لحذف نقطة توقف ، استخدم الأمر cl (مسح):<br />
</span></p>
<pre><code><span class="go">cl(ear) filename:lineno</span>
<span class="go">cl(ear) [bpnumber [bpnumber...]]</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">دعنا الآن نستخدم تعبير Python لتعيين نقطة توقف. تخيل موقفًا تريد التوقف فيه فقط إذا تلقت وظيفتك المضطربة مدخلات معينة.</p>
<p>في هذا السيناريو المثال ، تفشل وظيفة get_path () عندما تتلقى مسارًا نسبيًا ، أي أن مسار الملف لا يبدأ بـ /. سأقوم بإنشاء تعبير يتم تقييمه إلى صحيح في هذه الحالة وتمريره إلى b باعتباره الوسيطة الثانية:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example4.py 
<span class="gp">&gt;</span> /code/example4.py<span class="o">(</span><span class="m">7</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; filename_path = util.get_path(filename)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">b util.get_path, not filename.startswith('/')</span>
<span class="go">Breakpoint 1 at /code/util.py:1</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">c</span>
<span class="gp">&gt;</span> /code/util.py<span class="o">(</span><span class="m">3</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; import os</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">a</span>
<span class="go">filename = './example4.py'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بعد إنشاء نقطة التوقف أعلاه وإدخال c لمتابعة التنفيذ ، يتوقف pdb عند تقييم التعبير إلى true. يقوم الأمر a (args) بطباعة قائمة وسيطات الوظيفة الحالية.</p>
<p>في المثال أعلاه ، عندما تقوم بتعيين نقطة التوقف باستخدام اسم دالة بدلاً من رقم سطر ، لاحظ أن التعبير يجب أن يستخدم وسيطات الوظيفة فقط أو المتغيرات العامة المتاحة في وقت إدخال الوظيفة. خلاف ذلك ، ستتوقف نقطة التوقف عن التنفيذ في الوظيفة بغض النظر عن قيمة التعبير.</p>
<p>إذا كنت بحاجة إلى كسر استخدام تعبير باسم متغير موجود داخل دالة ، أي اسم متغير غير موجود في قائمة وسيطات الوظيفة ، فحدد رقم السطر:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example4.py 
<span class="gp">&gt;</span> /code/example4.py<span class="o">(</span><span class="m">7</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; filename_path = util.get_path(filename)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">b util:5, not head.startswith('/')</span>
<span class="go">Breakpoint 1 at /code/util.py:5</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">c</span>
<span class="gp">&gt;</span> /code/util.py<span class="o">(</span><span class="m">5</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p head</span>
<span class="go">'.'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">a</span>
<span class="go">filename = './example4.py'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكنك أيضًا تعيين نقطة توقف مؤقتة باستخدام الأمر tbreak. تتم إزالته تلقائيًا عندما يتم ضربه لأول مرة. يستخدم نفس الحجج مثل ب.</p>
<p><strong><span style="font-size: 20pt">استمرار التنفيذ</span></strong></p>
<p>حتى الآن ، نظرنا في التنقل عبر الشفرة باستخدام n (التالي) و s (الخطوة) واستخدام نقاط التوقف مع b (فاصل) و c (متابعة).</p>
<p>هناك أيضًا أمر مرتبط: unt (until).</p>
<p>استخدم unt لمواصلة التنفيذ مثل c ، لكن توقف عند السطر التالي أكبر من السطر الحالي. أحيانًا يكون unt أكثر ملاءمة وسرعة في الاستخدام وهو بالضبط ما تريده. سأوضح هذا بمثال أدناه.</p>
<p>دعونا نلقي نظرة أولية على بنية ووصف unt:<br />
وصف بناء جملة الأمر<br />
unt unt (il) [lineno] بدون لينينو ، استمر في التنفيذ حتى يتم الوصول إلى السطر الذي يحتوي على رقم أكبر من الرقم الحالي. باستخدام lineno ، استمر في التنفيذ حتى يتم الوصول إلى سطر برقم أكبر أو يساوي ذلك. في كلتا الحالتين ، توقف أيضًا عند عودة الإطار الحالي.</p>
<p>اعتمادًا على ما إذا كنت تمرر خط وسيطة رقم السطر أم لا ، يمكن أن يتصرف unt بطريقتين:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بدون لينينو ، استمر في التنفيذ حتى يتم الوصول إلى السطر الذي يحتوي على رقم أكبر من الرقم الحالي. هذا مشابه لـ n (next). إنها طريقة بديلة للتنفيذ و &#8220;التنقّل&#8221; للشفرة. الفرق بين n و unt هو أن unt يتوقف فقط عند الوصول إلى خط برقم أكبر من الرقم الحالي. سيتوقف n عند السطر التالي المنفذ منطقيًا.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">باستخدام lineno ، استمر في التنفيذ حتى يتم الوصول إلى سطر برقم أكبر أو يساوي ذلك. هذا مثل c (متابعة) مع وسيطة رقم سطر.<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في كلتا الحالتين ، unt يتوقف عند عودة الإطار الحالي (الوظيفة) ، تمامًا مثل n (التالي) و s (الخطوة).</p>
<p>استخدم unt عندما تريد متابعة التنفيذ والتوقف أكثر لأسفل في ملف المصدر الحالي. يمكنك معاملته على أنه مزيج من n (التالي) و b (فاصل) ، اعتمادًا على ما إذا كنت تمرر وسيطة رقم سطر أم لا.</p>
<p>في المثال أدناه ، توجد وظيفة ذات حلقة. هنا ، تريد متابعة تنفيذ الكود والتوقف بعد الحلقة ، دون المرور عبر كل تكرار للحلقة أو تعيين نقطة توقف:</p>
<p>إليك مثال المصدر على سبيل المثال example4unt.py:<br />
</span></p>
<pre><code><span class="ch">#!/usr/bin/env python3</span>

<span class="kn">import</span> <span class="nn">os</span>


<span class="k">def</span> <span class="nf">get_path</span><span class="p">(</span><span class="n">fname</span><span class="p">):</span>
    <span class="sd">"""Return file's path or empty string if no path."""</span>
    <span class="kn">import</span> <span class="nn">pdb</span><span class="p">;</span> <span class="n">pdb</span><span class="o">.</span><span class="n">set_trace</span><span class="p">()</span>
    <span class="n">head</span><span class="p">,</span> <span class="n">tail</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">fname</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">char</span> <span class="ow">in</span> <span class="n">tail</span><span class="p">:</span>
        <span class="k">pass</span>  <span class="c1"># Check filename char</span>
    <span class="k">return</span> <span class="n">head</span>


<span class="n">filename</span> <span class="o">=</span> <span class="vm">__file__</span>
<span class="n">filename_path</span> <span class="o">=</span> <span class="n">get_path</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'path = </span><span class="si">{</span><span class="n">filename_path</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">وإخراج وحدة التحكم باستخدام unt:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example4unt.py 
<span class="gp">&gt;</span> /code/example4unt.py<span class="o">(</span><span class="m">9</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; head, tail = os.path.split(fname)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">ll</span>
<span class="go">  6     def get_path(fname):</span>
<span class="go">  7         """Return file's path or empty string if no path."""</span>
<span class="go">  8         import pdb; pdb.set_trace()</span>
<span class="go">  9  -&gt;     head, tail = os.path.split(fname)</span>
<span class="go"> 10         for char in tail:</span>
<span class="go"> 11             pass  # Check filename char</span>
<span class="go"> 12         return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">unt</span>
<span class="gp">&gt;</span> /code/example4unt.py<span class="o">(</span><span class="m">10</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; for char in tail:</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> 
<span class="gp">&gt;</span> /code/example4unt.py<span class="o">(</span><span class="m">11</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; pass  # Check filename char</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> 
<span class="gp">&gt;</span> /code/example4unt.py<span class="o">(</span><span class="m">12</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p char, tail</span>
<span class="gp gp-VirtualEnv">('y', 'example4unt.py')</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تم استخدام الأمر ll أولاً لطباعة مصدر الوظيفة ، متبوعًا بـ unt. يتذكر pdb آخر أمر تم إدخاله ، لذلك قمت فقط بالضغط على Enter لتكرار الأمر unt. استمر هذا التنفيذ من خلال الكود حتى تم الوصول إلى سطر مصدر أكبر من السطر الحالي.</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ في إخراج وحدة التحكم أعلاه أن pdb توقف مرة واحدة فقط في السطرين 10 و 11. نظرًا لاستخدام unt ، تم إيقاف التنفيذ فقط في التكرار الأول للحلقة. ومع ذلك ، تم تنفيذ كل تكرار للحلقة. يمكن التحقق من ذلك في آخر سطر من الإخراج. قيمة &#8220;y&#8221; لمتغير char تساوي الحرف الأخير في قيمة &#8220;example4unt.py&#8221;.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">عرض التعبيرات</span></strong></p>
<p>على غرار تعبيرات الطباعة باستخدام p و pp ، يمكنك استخدام عرض الأمر [تعبير] لإخبار pdb بعرض قيمة التعبير تلقائيًا ، إذا تغيرت ، عند توقف التنفيذ. استخدم الأمر undisplay [التعبير] لمسح تعبير العرض.</p>
<p>فيما يلي بناء الجملة والوصف لكلا الأمرين:<br />
وصف بناء جملة الأمر<br />
display display [التعبير] يعرض قيمة التعبير إذا تغير ، في كل مرة يتوقف التنفيذ في الإطار الحالي. بدون تعبير ، قم بسرد كل تعبيرات العرض للإطار الحالي.<br />
undisplay undisplay [التعبير] لا تعرض أي تعبير في الإطار الحالي. بدون تعبير ، امسح كل تعبيرات العرض للإطار الحالي.</p>
<p>يوجد أدناه مثال ، example4display.py ، يوضح استخدامه مع حلقة:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example4display.py 
<span class="gp">&gt;</span> /code/example4display.py<span class="o">(</span><span class="m">9</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; head, tail = os.path.split(fname)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">ll</span>
<span class="go">  6     def get_path(fname):</span>
<span class="go">  7         """Return file's path or empty string if no path."""</span>
<span class="go">  8         import pdb; pdb.set_trace()</span>
<span class="go">  9  -&gt;     head, tail = os.path.split(fname)</span>
<span class="go"> 10         for char in tail:</span>
<span class="go"> 11             pass  # Check filename char</span>
<span class="go"> 12         return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">b 11</span>
<span class="go">Breakpoint 1 at /code/example4display.py:11</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">c</span>
<span class="gp">&gt;</span> /code/example4display.py<span class="o">(</span><span class="m">11</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; pass  # Check filename char</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">display char</span>
<span class="go">display char: 'e'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">c</span>
<span class="gp">&gt;</span> /code/example4display.py<span class="o">(</span><span class="m">11</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; pass  # Check filename char</span>
<span class="go">display char: 'x'  [old: 'e']</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> 
<span class="gp">&gt;</span> /code/example4display.py<span class="o">(</span><span class="m">11</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; pass  # Check filename char</span>
<span class="go">display char: 'a'  [old: 'x']</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> 
<span class="gp">&gt;</span> /code/example4display.py<span class="o">(</span><span class="m">11</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; pass  # Check filename char</span>
<span class="go">display char: 'm'  [old: 'a']</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في الإخراج أعلاه ، يعرض pdb تلقائيًا قيمة متغير char لأنه في كل مرة يتم فيها الوصول إلى نقطة التوقف ، تتغير قيمتها. في بعض الأحيان يكون هذا مفيدًا وهو ما تريده بالضبط ، ولكن هناك طريقة أخرى لاستخدام العرض.</p>
<p>يمكنك إدخال العرض عدة مرات لإنشاء قائمة مراقبة بالتعبيرات. يمكن أن يكون هذا أسهل في الاستخدام من p. بعد إضافة جميع التعبيرات التي تهتم بها ، ما عليك سوى إدخال العرض لرؤية القيم الحالية:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example4display.py 
<span class="gp">&gt;</span> /code/example4display.py<span class="o">(</span><span class="m">9</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; head, tail = os.path.split(fname)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">ll</span>
<span class="go">  6     def get_path(fname):</span>
<span class="go">  7         """Return file's path or empty string if no path."""</span>
<span class="go">  8         import pdb; pdb.set_trace()</span>
<span class="go">  9  -&gt;     head, tail = os.path.split(fname)</span>
<span class="go"> 10         for char in tail:</span>
<span class="go"> 11             pass  # Check filename char</span>
<span class="go"> 12         return head</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">b 11</span>
<span class="go">Breakpoint 1 at /code/example4display.py:11</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">c</span>
<span class="gp">&gt;</span> /code/example4display.py<span class="o">(</span><span class="m">11</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; pass  # Check filename char</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">display char</span>
<span class="go">display char: 'e'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">display fname</span>
<span class="go">display fname: './example4display.py'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">display head</span>
<span class="go">display head: '.'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">display tail</span>
<span class="go">display tail: 'example4display.py'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">c</span>
<span class="gp">&gt;</span> /code/example4display.py<span class="o">(</span><span class="m">11</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; pass  # Check filename char</span>
<span class="go">display char: 'x'  [old: 'e']</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">display</span>
<span class="go">Currently displaying:</span>
<span class="go">char: 'x'</span>
<span class="go">fname: './example4display.py'</span>
<span class="go">head: '.'</span>
<span class="go">tail: 'example4display.py'</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">معرف المتصل بيثون</span></strong></p>
<p>في هذا القسم الأخير ، سنبني على ما تعلمناه حتى الآن وننتهي بمكافأة جيدة. أستخدم اسم &#8220;معرف المتصل&#8221; في إشارة إلى ميزة تحديد هوية المتصل في نظام الهاتف. هذا هو بالضبط ما يوضحه هذا المثال ، باستثناء أنه يتم تطبيقه على بايثون.</p>
<p>إليك مصدر example5.py للنص البرمجي الرئيسي:<br />
</span></p>
<pre><code><span class="ch">#!/usr/bin/env python3</span>

<span class="kn">import</span> <span class="nn">fileutil</span>


<span class="k">def</span> <span class="nf">get_file_info</span><span class="p">(</span><span class="n">full_fname</span><span class="p">):</span>
    <span class="n">file_path</span> <span class="o">=</span> <span class="n">fileutil</span><span class="o">.</span><span class="n">get_path</span><span class="p">(</span><span class="n">full_fname</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">file_path</span>


<span class="n">filename</span> <span class="o">=</span> <span class="vm">__file__</span>
<span class="n">filename_path</span> <span class="o">=</span> <span class="n">get_file_info</span><span class="p">(</span><span class="n">filename</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s1">'path = </span><span class="si">{</span><span class="n">filename_path</span><span class="si">}</span><span class="s1">'</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إليك ملف وحدة الأداة المساعدة fileutil.py:<br />
</span></p>
<pre><code><span class="k">def</span> <span class="nf">get_path</span><span class="p">(</span><span class="n">fname</span><span class="p">):</span>
    <span class="sd">"""Return file's path or empty string if no path."""</span>
    <span class="kn">import</span> <span class="nn">os</span>
    <span class="kn">import</span> <span class="nn">pdb</span><span class="p">;</span> <span class="n">pdb</span><span class="o">.</span><span class="n">set_trace</span><span class="p">()</span>
    <span class="n">head</span><span class="p">,</span> <span class="n">tail</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="n">fname</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">head</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في هذا السيناريو ، تخيل وجود قاعدة رموز كبيرة مع وظيفة في وحدة الأداة المساعدة ، get_path () ، يتم استدعاؤها بإدخال غير صالح. ومع ذلك ، يتم استدعاؤه من عدة أماكن في حزم مختلفة.</p>
<p><strong>كيف تجد من هو المتصل؟</strong></p>
<p>استخدم الأمر w (حيث) لطباعة تتبع مكدس ، مع وجود أحدث إطار في الأسفل:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example5.py 
<span class="gp">&gt;</span> /code/fileutil.py<span class="o">(</span><span class="m">5</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; head, tail = os.path.split(fname)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">w</span>
<span class="go">  /code/example5.py(12)&lt;module&gt;()</span>
<span class="go">-&gt; filename_path = get_file_info(filename)</span>
<span class="go">  /code/example5.py(7)get_file_info()</span>
<span class="go">-&gt; file_path = fileutil.get_path(full_fname)</span>
<span class="gp">&gt;</span> /code/fileutil.py<span class="o">(</span><span class="m">5</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; head, tail = os.path.split(fname)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لا تقلق إذا كان هذا يبدو محيرًا أو إذا لم تكن متأكدًا من ماهية تتبع المكدس أو الإطار. سأشرح هذه الشروط أدناه. الأمر ليس بالصعوبة التي قد يبدو عليها.</p>
<p>نظرًا لأن أحدث إطار موجود في الأسفل ، ابدأ من هناك واقرأ من الأسفل إلى الأعلى. انظر إلى الأسطر التي تبدأ بـ -&gt; ، لكن تخطي المثال الأول حيث تم استخدام pdb.set_trace () لإدخال pdb في الدالة get_path (). في هذا المثال ، سطر المصدر الذي يسمى الدالة get_path () هو:<br />
</span></p>
<pre><code><span class="go">-&gt; file_path = fileutil.get_path(full_fname)</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">السطر الموجود أعلى كل -&gt; يحتوي على اسم الملف ورقم السطر (بين قوسين) واسم الوظيفة الموجود بها سطر المصدر. لذلك يكون المتصل هو:<br />
</span></p>
<pre><code><span class="go">/code/example5.py(7)get_file_info()</span>
<span class="go">-&gt; file_path = fileutil.get_path(full_fname)</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هذا ليس مفاجئًا في هذا المثال الصغير لأغراض التوضيح ، ولكن تخيل تطبيقًا كبيرًا حيث قمت بتعيين نقطة توقف بشرط لتحديد مكان إنشاء قيمة إدخال سيئة.</p>
<p>الآن نحن نعرف كيفية العثور على المتصل.</p>
<p><strong>ولكن ماذا عن هذا التتبع المكدس وإطار الأشياء؟</strong></p>
<p>تتبع المكدس هو مجرد قائمة بجميع الإطارات التي أنشأتها Python لتتبع استدعاءات الوظائف. الإطار عبارة عن بنية بيانات يتم إنشاؤها بواسطة Python عند استدعاء دالة وحذفها عند إعادتها. المكدس هو ببساطة قائمة مرتبة من الإطارات أو استدعاءات الوظائف في أي وقت. ينمو مكدس (استدعاء الوظيفة) ويتقلص طوال عمر التطبيق حيث يتم استدعاء الوظائف ثم العودة.</p>
<p>عند طباعتها ، تسمى هذه القائمة المرتبة من الإطارات ، المكدس ، تتبع المكدس. يمكنك رؤيته في أي وقت عن طريق إدخال الأمر w ، كما فعلنا أعلاه للعثور على المتصل.<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">راجع مقالة مكدس المكالمات هذه على ويكيبيديا للحصول على التفاصيل.</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لفهم أفضل والاستفادة بشكل أكبر من pdb ، دعنا نلقي نظرة عن كثب على المساعدة الخاصة بـ w:<br />
</span></p>
<pre><code><span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">h w</span>
<span class="go">w(here)</span>
<span class="go">        Print a stack trace, with the most recent frame at the bottom.</span>
<span class="go">        An arrow indicates the "current frame", which determines the</span>
<span class="go">        context of most commands. 'bt' is an alias for this command.</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>ماذا يعني pdb ب &#8220;الإطار الحالي&#8221;؟</strong></p>
<p>فكر في الإطار الحالي على أنه الوظيفة الحالية حيث توقف pdb عن التنفيذ. بمعنى آخر ، الإطار الحالي هو المكان الذي يتم فيه إيقاف التطبيق مؤقتًا حاليًا ويتم استخدامه كـ &#8220;إطار&#8221; مرجعي لأوامر pdb مثل p (طباعة).</p>
<p>ستستخدم p والأوامر الأخرى الإطار الحالي للسياق عند الحاجة. في حالة p ، سيتم استخدام الإطار الحالي للبحث عن المراجع المتغيرة وطباعتها.</p>
<p>عندما يقوم pdb بطباعة تتبع مكدس ، يشير السهم&gt; إلى الإطار الحالي.</p>
<p><strong>كيف هذا مفيد؟</strong></p>
<p>يمكنك استخدام الأمرين u (أعلى) و د (أسفل) لتغيير الإطار الحالي. بالاقتران مع p ، يتيح لك ذلك فحص المتغيرات والحالة في التطبيق الخاص بك في أي نقطة على طول مكدس الاستدعاءات في أي إطار.</p>
<p>فيما يلي بناء الجملة والوصف لكلا الأمرين:</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">وصف بناء جملة الأمر<br />
u u (p) [عدد] نقل عدد الإطارات الحالي (المستوى الافتراضي) إلى أعلى في تتبع المكدس (إلى إطار أقدم).<br />
d d (خاص) [عدد] نقل مستويات عدد الإطارات الحالية (المستوى الافتراضي) لأسفل في تتبع المكدس (إلى إطار أحدث).</p>
<p>دعونا نلقي نظرة على مثال باستخدام الأمرين u و d. في هذا السيناريو ، نريد فحص المتغير full_fname المحلي للدالة get_file_info () في example5.py. للقيام بذلك ، يتعين علينا تغيير الإطار الحالي إلى مستوى أعلى باستخدام الأمر u:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example5.py 
<span class="gp">&gt;</span> /code/fileutil.py<span class="o">(</span><span class="m">5</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; head, tail = os.path.split(fname)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">w</span>
<span class="go">  /code/example5.py(12)&lt;module&gt;()</span>
<span class="go">-&gt; filename_path = get_file_info(filename)</span>
<span class="go">  /code/example5.py(7)get_file_info()</span>
<span class="go">-&gt; file_path = fileutil.get_path(full_fname)</span>
<span class="gp">&gt;</span> /code/fileutil.py<span class="o">(</span><span class="m">5</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; head, tail = os.path.split(fname)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">u</span>
<span class="gp">&gt;</span> /code/example5.py<span class="o">(</span><span class="m">7</span><span class="o">)</span>get_file_info<span class="o">()</span>
<span class="go">-&gt; file_path = fileutil.get_path(full_fname)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p full_fname</span>
<span class="go">'./example5.py'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">d</span>
<span class="gp">&gt;</span> /code/fileutil.py<span class="o">(</span><span class="m">5</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; head, tail = os.path.split(fname)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p fname</span>
<span class="go">'./example5.py'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الاستدعاء إلى pdb.set_trace () موجود في fileutil.py في الوظيفة get_path () ، لذلك يتم تعيين الإطار الحالي هناك في البداية. يمكنك رؤيته في السطر الأول من الإخراج أعلاه:<br />
</span></p>
<pre><code><span class="gp">&gt;</span> /code/fileutil.py<span class="o">(</span><span class="m">5</span><span class="o">)</span>get_path<span class="o">()</span></code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">للوصول إلى المتغير المحلي full_fname وطباعته في الوظيفة get_file_info () في example5.py ، تم استخدام الأمر u للانتقال إلى مستوى واحد للأعلى:<br />
</span></p>
<pre><code><span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">u</span>
<span class="gp">&gt;</span> /code/example5.py<span class="o">(</span><span class="m">7</span><span class="o">)</span>get_file_info<span class="o">()</span>
<span class="go">-&gt; file_path = fileutil.get_path(full_fname)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ في إخراج u أعلاه أن pdb طبع السهم&gt; في بداية السطر الأول. يتيح لك هذا pdb معرفة أنه تم تغيير الإطار وأن موقع المصدر هذا هو الآن الإطار الحالي. المتغير full_fname يمكن الوصول إليه الآن. أيضًا ، من المهم إدراك أن سطر المصدر الذي يبدأ بـ -&gt; في السطر الثاني قد تم تنفيذه. منذ أن تم نقل الإطار لأعلى المكدس ، تم استدعاء fileutil.get_path (). باستخدام u ، نقلنا المكدس (بمعنى ما ، إلى الوراء في الوقت المناسب) إلى الوظيفة example5.get_file_info () حيث تم استدعاء fileutil.get_path ().</p>
<p>متابعة للمثال ، بعد طباعة full_fname ، تم نقل الإطار الحالي إلى موقعه الأصلي باستخدام d ، وتمت طباعة المتغير المحلي fname في get_path ().</p>
<p>إذا أردنا ذلك ، كان بإمكاننا تحريك إطارات متعددة مرة واحدة بتمرير وسيطة العد إلى u أو d. على سبيل المثال ، كان بإمكاننا الانتقال إلى مستوى الوحدة النمطية في example5.py عن طريق إدخال u 2:<br />
</span></p>
<pre><code><span class="gp">$</span> ./example5.py 
<span class="gp">&gt;</span> /code/fileutil.py<span class="o">(</span><span class="m">5</span><span class="o">)</span>get_path<span class="o">()</span>
<span class="go">-&gt; head, tail = os.path.split(fname)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">u 2</span>
<span class="gp">&gt;</span> /code/example5.py<span class="o">(</span><span class="m">12</span><span class="o">)</span>&lt;module&gt;<span class="o">()</span>
<span class="go">-&gt; filename_path = get_file_info(filename)</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> <span class="go">p filename</span>
<span class="go">'./example5.py'</span>
<span class="gp gp-VirtualEnv">(Pdb)</span> </code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">من السهل أن تنسى مكانك عند تصحيح الأخطاء والتفكير في العديد من الأشياء المختلفة. فقط تذكر أنه يمكنك دائمًا استخدام الأمر w (حيث) المسمى بشكل مناسب لمعرفة مكان إيقاف التنفيذ مؤقتًا وما هو الإطار الحالي.</p>
<p><strong><span style="font-size: 20pt">أوامر pdb الأساسية</span></strong></p>
<p>بمجرد قضاء بعض الوقت مع pdb ، ستدرك أن القليل من المعرفة يقطع شوطًا طويلاً. المساعدة متاحة دائمًا مع الأمر h.</p>
<p>ما عليك سوى إدخال h أو مساعدة &lt;topic&gt; للحصول على قائمة بجميع الأوامر أو المساعدة لأمر أو موضوع معين.</p>
<p>للإشارة بسرعة ، إليك قائمة بالأوامر الأساسية:<br />
وصف الأمر<br />
p طباعة قيمة التعبير.<br />
ص ب جميلة &#8211; طباعة قيمة التعبير.<br />
n تابع التنفيذ حتى يتم الوصول إلى السطر التالي في الوظيفة الحالية أو يعود.<br />
قم بتنفيذ السطر الحالي وتوقف عند أول مناسبة ممكنة (إما في وظيفة تسمى أو في الوظيفة الحالية).<br />
ج مواصلة التنفيذ والتوقف فقط عند مواجهة نقطة توقف.<br />
استمر في التنفيذ حتى يتم الوصول إلى السطر الذي يحتوي على رقم أكبر من الرقم الحالي. باستخدام وسيطة رقم سطر ، استمر في التنفيذ حتى يتم الوصول إلى سطر برقم أكبر أو يساوي ذلك.<br />
l سرد التعليمات البرمجية المصدر للملف الحالي. بدون وسيطات ، قم بإدراج 11 سطراً حول السطر الحالي أو تابع القائمة السابقة.<br />
ll قائمة التعليمات البرمجية المصدر بالكامل للوظيفة الحالية أو الإطار.<br />
ب دون أي حجج ، قم بإدراج جميع الفواصل. باستخدام وسيطة رقم السطر ، قم بتعيين نقطة توقف عند هذا السطر في الملف الحالي.<br />
w اطبع تتبع مكدس ، بحيث يكون أحدث إطار في الأسفل. يشير السهم إلى الإطار الحالي ، والذي يحدد سياق معظم الأوامر.<br />
u انقل مستويات عدد الإطارات الحالية (المستوى الافتراضي) لأعلى في تتبع المكدس (إلى إطار أقدم).<br />
d انقل مستويات عدد الإطارات الحالية (المستوى الافتراضي) لأسفل في تتبع المكدس (إلى إطار أحدث).<br />
h راجع قائمة بالأوامر المتوفرة.<br />
h &lt;topic&gt; إظهار التعليمات لأمر أو موضوع.<br />
h pdb إظهار وثائق pdb الكاملة.<br />
q قم بإنهاء مصحح الأخطاء والإنهاء.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">تصحيح أخطاء بايثون باستخدام PDB: الخاتمة</span></strong></p>
<p>في هذا البرنامج التعليمي ، غطينا بعض الاستخدامات الأساسية والشائعة لـ pdb:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تعبيرات الطباعة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يتخطى الكود مع n (التالي) و s (خطوة)<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">باستخدام نقاط التوقف<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">استمرار التنفيذ مع unt (حتى)<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عرض التعبيرات<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">العثور على متصل دالة<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">آمل أن تكون مفيدة لك. إذا كنت مهتمًا بمعرفة المزيد ، فراجع:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">وثائق pdb الكاملة في موجه pdb بالقرب منك: (Pdb) h pdb<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">مستندات pdb من Python<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن العثور على الكود المصدري المستخدم في الأمثلة في مستودع GitHub المرتبط. تأكد من إطلاعك على مرجع أوامر pdb القابل للطباعة ، والذي يمكنك استخدامه كورقة غش أثناء تصحيح الأخطاء:</p>
<p>أيضًا ، إذا كنت ترغب في تجربة مصحح أخطاء Python المستند إلى واجهة المستخدم الرسومية ، فاقرأ Python IDEs and Editors Guide لمعرفة الخيارات التي ستناسبك بشكل أفضل. بايثونينج سعيد!</span></p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d8%aa%d8%b5%d8%ad%d9%8a%d8%ad-%d8%a3%d8%ae%d8%b7%d8%a7%d8%a1-python-%d8%a8%d8%a7%d8%b3%d8%aa%d8%ae%d8%af%d8%a7%d9%85-pdb/">تصحيح أخطاء Python باستخدام Pdb</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://arabdars.com/%d8%aa%d8%b5%d8%ad%d9%8a%d8%ad-%d8%a3%d8%ae%d8%b7%d8%a7%d8%a1-python-%d8%a8%d8%a7%d8%b3%d8%aa%d8%ae%d8%af%d8%a7%d9%85-pdb/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>11 نصائح للمبتدئين لتعلم برمجة بايثون</title>
		<link>https://arabdars.com/11-%d9%86%d8%b5%d8%a7%d8%a6%d8%ad-%d9%84%d9%84%d9%85%d8%a8%d8%aa%d8%af%d8%a6%d9%8a%d9%86-%d9%84%d8%aa%d8%b9%d9%84%d9%85-%d8%a8%d8%b1%d9%85%d8%ac%d8%a9-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/</link>
					<comments>https://arabdars.com/11-%d9%86%d8%b5%d8%a7%d8%a6%d8%ad-%d9%84%d9%84%d9%85%d8%a8%d8%aa%d8%af%d8%a6%d9%8a%d9%86-%d9%84%d8%aa%d8%b9%d9%84%d9%85-%d8%a8%d8%b1%d9%85%d8%ac%d8%a9-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/#respond</comments>
		
		<dc:creator><![CDATA[Reyhane]]></dc:creator>
		<pubDate>Thu, 17 Sep 2020 08:32:43 +0000</pubDate>
				<category><![CDATA[الماتلاب Matlab]]></category>
		<guid isPermaLink="false">https://arabdars.com/?p=1617</guid>

					<description><![CDATA[<p>جدول المحتويات اجعلها تلتصق النصيحة رقم 1: كود كل يوم النصيحة الثانية: اكتبها نصيحة رقم 3: انطلق التفاعلي! نصيحة رقم 4: خذ فترات راحة نصيحة رقم 5: كن صيادًا من Bug Bounty اجعلها تعاونية نصيحة رقم 6: أحط نفسك بالآخرين الذين يتعلمون نصيحة رقم 7: علم نصيحة رقم 8: برنامج الزوج النصيحة رقم 9: اطرح [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://arabdars.com/11-%d9%86%d8%b5%d8%a7%d8%a6%d8%ad-%d9%84%d9%84%d9%85%d8%a8%d8%aa%d8%af%d8%a6%d9%8a%d9%86-%d9%84%d8%aa%d8%b9%d9%84%d9%85-%d8%a8%d8%b1%d9%85%d8%ac%d8%a9-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/">11 نصائح للمبتدئين لتعلم برمجة بايثون</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">جدول المحتويات</span></strong></p>
<p></span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">اجعلها تلتصق<br />
النصيحة رقم 1: كود كل يوم<br />
النصيحة الثانية: اكتبها<br />
نصيحة رقم 3: انطلق التفاعلي!<br />
نصيحة رقم 4: خذ فترات راحة<br />
نصيحة رقم 5: كن صيادًا من Bug Bounty<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">اجعلها تعاونية<br />
نصيحة رقم 6: أحط نفسك بالآخرين الذين يتعلمون<br />
نصيحة رقم 7: علم<br />
نصيحة رقم 8: برنامج الزوج<br />
النصيحة رقم 9: اطرح أسئلة &#8220;جيدة&#8221;<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">اصنع شيئا<br />
النصيحة رقم 10: ابني شيئًا ، أي شيء<br />
نصيحة رقم 11: المساهمة في المصدر المفتوح<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">انطلق وتعلم!<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">نحن متحمسون للغاية لأنك قررت الشروع في رحلة تعلم بايثون! أحد الأسئلة الأكثر شيوعًا التي نتلقاها من قرائنا هو &#8220;ما هي أفضل طريقة لتعلم بايثون؟&#8221;</p>
<p>أعتقد أن الخطوة الأولى في تعلم أي لغة برمجة هي التأكد من فهمك لكيفية التعلم. يمكن القول إن تعلم كيفية التعلم هو أهم المهارات التي ينطوي عليها برمجة الكمبيوتر.</p>
<p>لماذا معرفة كيفية التعلم مهم جدا؟ الجواب بسيط: مع تطور اللغات ، يتم إنشاء المكتبات وترقية الأدوات. ستكون معرفة كيفية التعلم ضرورية لمواكبة هذه التغييرات وأن تصبح مبرمجًا ناجحًا.</p>
<p>في هذه المقالة ، سوف نقدم العديد من استراتيجيات التعلم التي ستساعدك على بدء رحلتك لتصبح مبرمجًا في لغة الروك بايثون!</p>
<p><strong><span style="font-size: 20pt">اجعلها تلتصق</span></strong></p>
<p>فيما يلي بعض النصائح لمساعدتك على جعل المفاهيم الجديدة التي تتعلمها كمبرمج مبتدئ ثابتة حقًا:<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>النصيحة رقم 1: كود كل يوم</strong></p>
<p>الاتساق مهم جدًا عندما تتعلم لغة جديدة. نوصي بالالتزام بالرمز كل يوم. قد يكون من الصعب تصديق ذلك ، لكن ذاكرة العضلات تلعب دورًا كبيرًا في البرمجة. الالتزام بالبرمجة يوميًا سيساعد حقًا في تطوير ذاكرة العضلات. على الرغم من أن الأمر قد يبدو شاقًا في البداية ، ففكر في البدء لمدة 25 دقيقة يوميًا والعمل في طريقك من هناك.</p>
<p>تحقق من First Steps With Python Guide للحصول على معلومات حول الإعداد بالإضافة إلى التدريبات للبدء.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>النصيحة الثانية: اكتبها</strong></p>
<p>مع تقدمك في رحلتك كمبرمج جديد ، قد تتساءل عما إذا كان عليك تدوين الملاحظات. نعم يجب عليك! في الواقع ، تشير الأبحاث إلى أن تدوين الملاحظات يدويًا هو أكثر فائدة للاحتفاظ بها على المدى الطويل. سيكون هذا مفيدًا بشكل خاص لأولئك الذين يعملون من أجل تحقيق هدف أن يصبحوا مطورًا بدوام كامل ، حيث ستشمل العديد من المقابلات كتابة التعليمات البرمجية على السبورة.</p>
<p>بمجرد أن تبدأ العمل في المشاريع والبرامج الصغيرة ، يمكن أن تساعدك الكتابة اليدوية أيضًا في تخطيط التعليمات البرمجية الخاصة بك قبل الانتقال إلى الكمبيوتر. يمكنك توفير الكثير من الوقت إذا كتبت الوظائف والفصول التي ستحتاجها ، وكذلك كيفية تفاعلها.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>نصيحة رقم 3: انطلق التفاعلي!</strong></p>
<p>سواء كنت تتعلم عن هياكل بيانات Python الأساسية (سلاسل ، قوائم ، قواميس ، إلخ) لأول مرة ، أو كنت تقوم بتصحيح تطبيق ، فإن Python shell التفاعلية ستكون واحدة من أفضل أدوات التعلم لديك. نحن نستخدمه كثيرا في هذا الموقع أيضا!</p>
<p>لاستخدام قشرة Python التفاعلية (تسمى أحيانًا &#8220;Python REPL&#8221;) ، تأكد أولاً من تثبيت Python على جهاز الكمبيوتر الخاص بك. لدينا برنامج تعليمي خطوة بخطوة لمساعدتك على القيام بذلك. لتنشيط غلاف Python التفاعلي ، ما عليك سوى فتح الجهاز وتشغيل python أو python3 اعتمادًا على التثبيت الخاص بك. يمكنك العثور على مزيد من التوجيهات المحددة هنا.</p>
<p>الآن بعد أن عرفت كيف تبدأ الصدفة ، إليك بعض الأمثلة عن كيفية استخدام الصدفة عندما تتعلم:</p>
<p><strong>تعرف على العمليات التي يمكن إجراؤها على عنصر باستخدام dir ():</strong></span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">my_string</span> <span class="o">=</span> <span class="s1">'I am a string'</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">(</span><span class="n">my_string</span><span class="p">)</span>
<span class="go">['__add__', ..., 'upper', 'zfill']  # Truncated for readability</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">العناصر التي يتم إرجاعها من dir () هي جميع الطرق (أي الإجراءات) التي يمكنك تطبيقها على العنصر. فمثلا:</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">my_string</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="s1">'I AM A STRING'</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لاحظ أننا أطلقنا عليها طريقة () العليا. هل تستطيع أن ترى ما تفعله؟ يجعل كل الأحرف في السلسلة كبيرة! تعرف على المزيد حول هذه الأساليب المضمنة ضمن &#8220;معالجة السلاسل&#8221; في هذا البرنامج التعليمي.</p>
<p><strong>تعرف على نوع العنصر:</strong></span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="nb">type</span><span class="p">(</span><span class="n">my_string</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">str</span>
</code></pre>
<p><strong><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">استخدم نظام المساعدة المدمج للحصول على الوثائق الكاملة:</span></strong></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">help</span><span class="p">(</span><span class="nb">str</span><span class="p">)</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>استيراد المكتبات واللعب معهم:</strong></span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">(</span><span class="n">datetime</span><span class="p">)</span>
<span class="go">['__add__', ..., 'weekday', 'year']  # Truncated for readability</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span>
<span class="go">datetime.datetime(2018, 3, 14, 23, 44, 50, 851904)</span>
</code></pre>
<p><strong><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تشغيل أوامر shell:</span></strong></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">os</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">'ls'</span><span class="p">)</span>
<span class="go">python_hw1.py python_hw2.py README.txt</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>نصيحة رقم 4: خذ فترات راحة</strong></p>
<p>عندما تتعلم ، من المهم الابتعاد واستيعاب المفاهيم. تُستخدم تقنية بومودورو على نطاق واسع ويمكن أن تساعدك: تعمل لمدة 25 دقيقة ، وتأخذ استراحة قصيرة ، ثم تكرر العملية. أخذ فترات راحة أمر بالغ الأهمية للحصول على جلسة دراسة فعالة ، لا سيما عندما تأخذ الكثير من المعلومات الجديدة.</p>
<p>تعتبر الفواصل مهمة بشكل خاص عند تصحيح الأخطاء. إذا واجهت خطأ ولم تتمكن من اكتشاف الخطأ الذي يحدث ، خذ قسطًا من الراحة. ابتعد عن جهاز الكمبيوتر أو انطلق في نزهة على الأقدام أو تحدث مع صديق.</p>
<p>في البرمجة ، يجب أن تتبع التعليمات البرمجية الخاصة بك قواعد اللغة والمنطق تمامًا ، لذلك حتى لو فقدت علامة اقتباس سوف يكسر كل شيء. العيون الجديدة تحدث فرقًا كبيرًا.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>نصيحة رقم 5: كن صيادًا من Bug Bounty</strong></p>
<p>عند الحديث عن حدوث خطأ ، فإنه أمر لا مفر منه بمجرد أن تبدأ في كتابة البرامج المعقدة التي ستواجه أخطاء في التعليمات البرمجية الخاصة بك. يحدث لنا جميعا! لا تدع الحشرات تحبطك. بدلاً من ذلك ، احتضن هذه اللحظات بكل فخر وفكر في نفسك كصائد جوائز.</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عند تصحيح الأخطاء ، من المهم أن يكون لديك نهج منهجي لمساعدتك في العثور على الأماكن التي تتعطل فيها الأشياء. يعد تصفح الكود الخاص بك بالترتيب الذي تم تنفيذه به والتأكد من عمل كل جزء طريقة رائعة للقيام بذلك.</p>
<p>بمجرد أن تكون لديك فكرة عن المكان الذي قد تتعطل فيه الأشياء ، أدخل السطر التالي من التعليمات البرمجية في البرنامج النصي import pdb ؛ pdb.set_trace () وتشغيله. هذا هو مصحح أخطاء Python وسوف ينقلك إلى الوضع التفاعلي. يمكن أيضًا تشغيل مصحح الأخطاء من سطر الأوامر باستخدام python -m pdb &lt;my_file.py&gt;.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">اجعلها تعاونية</span></strong></p>
<p>بمجرد أن تبدأ الأشياء في التمسك ، قم بتسريع التعلم من خلال التعاون. فيما يلي بعض الإستراتيجيات لمساعدتك على تحقيق أقصى استفادة من العمل مع الآخرين.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>نصيحة رقم 6: أحط نفسك بالآخرين الذين يتعلمون</strong></p>
<p>على الرغم من أن البرمجة قد تبدو وكأنها نشاط فردي ، إلا أنها تعمل بشكل أفضل عندما تعمل معًا. من المهم للغاية عندما تتعلم البرمجة في بايثون أن تحيط نفسك بأشخاص آخرين يتعلمون أيضًا. سيسمح لك ذلك بمشاركة النصائح والحيل التي تتعلمها على طول الطريق.</p>
<p>لا تقلق إذا كنت لا تعرف أحداً. هناك الكثير من الطرق لمقابلة الآخرين المتحمسين لتعلم بايثون! ابحث عن الأحداث المحلية أو اللقاءات أو انضم إلى PythonistaCafe ، وهو مجتمع التعلم من نظير إلى نظير لعشاق Python مثلك!<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>نصيحة رقم 7: علم</strong></p>
<p>يقال أن أفضل طريقة لتعلم شيء ما هي تعليمه. هذا صحيح عندما تتعلم بايثون. هناك العديد من الطرق للقيام بذلك: استخدام السبورة البيضاء مع محبي بايثون الآخرين ، أو كتابة منشورات مدونة تشرح المفاهيم المكتسبة حديثًا ، أو تسجيل مقاطع فيديو تشرح فيها شيئًا ما تعلمته ، أو مجرد التحدث إلى نفسك على جهاز الكمبيوتر الخاص بك. ستعمل كل من هذه الاستراتيجيات على ترسيخ فهمك وكذلك الكشف عن أي فجوات في فهمك.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>نصيحة رقم 8: برنامج الزوج</strong></p>
<p>البرمجة الزوجية هي تقنية تتضمن مطورين يعملان في محطة عمل واحدة لإكمال مهمة. يقوم المطوران بالتبديل بين كونهما &#8220;السائق&#8221; و &#8220;الملاح&#8221;. يقوم &#8220;السائق&#8221; بكتابة الكود ، بينما &#8220;الملاح&#8221; يساعد في توجيه حل المشكلات ومراجعة الكود كما هو مكتوب. قم بالتبديل بشكل متكرر للاستفادة من كلا الجانبين.</p>
<p>تتمتع البرمجة الزوجية بالعديد من الفوائد: فهي تمنحك فرصة ليس فقط لجعل شخص ما يراجع التعليمات البرمجية الخاصة بك ، ولكن أيضًا لمعرفة كيف قد يفكر شخص آخر في مشكلة ما. سيساعدك التعرض لأفكار وطرق تفكير متعددة في حل المشكلات عندما تعود إلى البرمجة بنفسك.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>النصيحة رقم 9: اطرح أسئلة &#8220;جيدة&#8221;</strong></p>
<p>يقول الناس دائمًا أنه لا يوجد شيء اسمه سؤال سيء ، ولكن عندما يتعلق الأمر بالبرمجة ، فمن الممكن طرح سؤال بشكل سيء. عندما تطلب المساعدة من شخص لديه القليل من السياق أو لا يوجد سياق له حول المشكلة التي تحاول حلها ، فمن الأفضل أن تطرح أسئلة جيدة باتباع هذا الاختصار:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ز: أعط سياقًا لما تحاول القيام به ، واصفًا المشكلة بوضوح.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">س: حدد الخطوط العريضة للأشياء التي حاولت بالفعل إصلاحها.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">س: قدِّم أفضل تخمين لديك لما قد تكون عليه المشكلة. يساعد هذا الشخص الذي يساعدك ليس فقط على معرفة ما تفكر فيه ، ولكن أيضًا على معرفة أنك قد قمت ببعض التفكير بنفسك.<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">D</span><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">: عرض ما يحدث. قم بتضمين الرمز ، ورسالة خطأ في التتبع ، وشرح للخطوات التي نفذتها وأدت إلى حدوث الخطأ. بهذه الطريقة ، لا يتعين على الشخص الذي يساعد أن يحاول إعادة إنشاء المشكلة.<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن أن توفر الأسئلة الجيدة الكثير من الوقت. يمكن أن يؤدي تخطي أي من هذه الخطوات إلى إجراء محادثات ذهابًا وإيابًا قد تتسبب في حدوث تعارض. كمبتدئ ، فأنت تريد التأكد من طرح أسئلة جيدة حتى تتدرب على توصيل عملية تفكيرك ، وحتى يسعد الأشخاص الذين يساعدونك بمواصلة مساعدتك.</p>
<p><strong><span style="font-size: 20pt">اصنع شيئا</span></strong></p>
<p>سيخبرك معظم مطوري Python الذين تتحدث معهم ، إن لم يكن جميعهم ، أنه من أجل تعلم Python ، يجب أن تتعلم من خلال العمل. يمكن أن تأخذك التمارين حتى الآن: فأنت تتعلم أكثر من خلال البناء.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>النصيحة رقم 10: ابني شيئًا ، أي شيء</strong></p>
<p>للمبتدئين ، هناك العديد من التمارين الصغيرة التي ستساعدك حقًا على أن تصبح واثقًا من نفسك مع بايثون ، بالإضافة إلى تطوير ذاكرة العضلات التي تحدثنا عنها أعلاه. بمجرد أن يكون لديك فهم قوي لهياكل البيانات الأساسية (سلاسل ، قوائم ، قواميس ، مجموعات) ، البرمجة الشيئية ، وفصول الكتابة ، حان الوقت لبدء البناء!</p>
<p>ما تقوم ببنائه ليس بنفس أهمية كيفية بنائه. رحلة البناء هي حقًا ما سيعلمك أكثر. يمكنك فقط تعلم الكثير من قراءة مقالات ودورات Real Python. سيأتي معظم تعلمك من استخدام Python لبناء شيء ما. المشاكل التي ستحلها ستعلمك الكثير.</p>
<p>هناك العديد من القوائم التي تحتوي على أفكار لمشاريع بايثون للمبتدئين. اليك بعض الافكار للبدء:<br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لعبة التخمين العدد<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تطبيق آلة حاسبة بسيط<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">محاكاة لفة النرد<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">خدمة الإعلام عن أسعار البيتكوين</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إذا وجدت صعوبة في التوصل إلى مشاريع تدريب على Python للعمل عليها ، شاهد هذا الفيديو. إنه يضع استراتيجية يمكنك استخدامها لتوليد الآلاف من أفكار المشاريع كلما شعرت بالعجز.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong>نصيحة رقم 11: المساهمة في المصدر المفتوح</strong></p>
<p>في نموذج المصدر المفتوح ، تكون شفرة مصدر البرنامج متاحة للجمهور ، ويمكن لأي شخص التعاون. هناك العديد من مكتبات Python التي تعد مشروعات مفتوحة المصدر وتتلقى المساهمات. بالإضافة إلى ذلك ، تنشر العديد من الشركات مشاريع مفتوحة المصدر. هذا يعني أنه يمكنك العمل مع التعليمات البرمجية المكتوبة والمنتجة من قبل المهندسين العاملين في هذه الشركات.</p>
<p>تعد المساهمة في مشروع Python مفتوح المصدر طريقة رائعة لإنشاء خبرات تعليمية قيمة للغاية. لنفترض أنك قررت إرسال طلب إصلاح الخطأ: فأنت ترسل &#8220;طلب سحب&#8221; لإصلاحك في الشفرة.</p>
<p>بعد ذلك ، سيراجع مديرو المشروع عملك ، ويقدمون التعليقات والاقتراحات. سيمكنك هذا من تعلم أفضل الممارسات لبرمجة Python ، بالإضافة إلى ممارسة التواصل مع المطورين الآخرين.</p>
<p>للحصول على مزيد من النصائح والتكتيكات التي ستساعدك على اقتحام عالم مفتوح المصدر ، تحقق من الفيديو المضمن أدناه:</p>
<p><strong><span style="font-size: 20pt">انطلق وتعلم!</span></strong></p>
<p>الآن بعد أن أصبحت لديك هذه الاستراتيجيات للتعلم ، فأنت جاهز لبدء رحلة Python! ابحث عن خارطة طريق Real Python للمبتدئين للتعلم هنا! نقدم أيضًا دورة Python للمستوى المبتدئين ، والتي تستخدم أمثلة مثيرة للاهتمام لمساعدتك على تعلم البرمجة وتطوير الويب.</p>
<p>ترميز سعيد!</span></p>
<p>The post <a rel="nofollow" href="https://arabdars.com/11-%d9%86%d8%b5%d8%a7%d8%a6%d8%ad-%d9%84%d9%84%d9%85%d8%a8%d8%aa%d8%af%d8%a6%d9%8a%d9%86-%d9%84%d8%aa%d8%b9%d9%84%d9%85-%d8%a8%d8%b1%d9%85%d8%ac%d8%a9-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/">11 نصائح للمبتدئين لتعلم برمجة بايثون</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://arabdars.com/11-%d9%86%d8%b5%d8%a7%d8%a6%d8%ad-%d9%84%d9%84%d9%85%d8%a8%d8%aa%d8%af%d8%a6%d9%8a%d9%86-%d9%84%d8%aa%d8%b9%d9%84%d9%85-%d8%a8%d8%b1%d9%85%d8%ac%d8%a9-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>التفكير التكراري في بايثون</title>
		<link>https://arabdars.com/%d8%a7%d9%84%d8%aa%d9%81%d9%83%d9%8a%d8%b1-%d8%a7%d9%84%d8%aa%d9%83%d8%b1%d8%a7%d8%b1%d9%8a-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/</link>
					<comments>https://arabdars.com/%d8%a7%d9%84%d8%aa%d9%81%d9%83%d9%8a%d8%b1-%d8%a7%d9%84%d8%aa%d9%83%d8%b1%d8%a7%d8%b1%d9%8a-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/#respond</comments>
		
		<dc:creator><![CDATA[Reyhane]]></dc:creator>
		<pubDate>Thu, 17 Sep 2020 08:13:49 +0000</pubDate>
				<category><![CDATA[الماتلاب Matlab]]></category>
		<guid isPermaLink="false">https://arabdars.com/?p=1610</guid>

					<description><![CDATA[<p>جدول المحتويات عزيزي سانتا كلوز البيثوني &#8230; الوظائف العودية في بايثون الحفاظ على الدولة هياكل البيانات العودية في بايثون التكرار الساذج هو ساذج تفاصيل مزعجة زعنفة المراجع &#8220;من بين جميع الأفكار التي قدمتها للأطفال ، تبرز العودية باعتبارها الفكرة الوحيدة القادرة بشكل خاص على إثارة استجابة حماسية.&#8221; &#8211; سيمور بابيرت ، Mindstorms غالبًا ما تبدو [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d8%a7%d9%84%d8%aa%d9%81%d9%83%d9%8a%d8%b1-%d8%a7%d9%84%d8%aa%d9%83%d8%b1%d8%a7%d8%b1%d9%8a-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/">التفكير التكراري في بايثون</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">جدول المحتويات</span></strong><br />
</span></p>
<ul>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">عزيزي سانتا كلوز البيثوني &#8230;<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الوظائف العودية في بايثون<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الحفاظ على الدولة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هياكل البيانات العودية في بايثون<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">التكرار الساذج هو ساذج<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تفاصيل مزعجة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">زعنفة<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">المراجع<br />
</span></li>
</ul>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">&#8220;من بين جميع الأفكار التي قدمتها للأطفال ، تبرز العودية باعتبارها الفكرة الوحيدة القادرة بشكل خاص على إثارة استجابة حماسية.&#8221;</span></p>
<p><span style="font-size: 14pt">&#8211; سيمور بابيرت ، Mindstorms</span></p></blockquote>
<p><a href="https://files.realpython.com/media/fixing_problems.ffd6d34e887e.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block  aligncenter" src="https://files.realpython.com/media/fixing_problems.ffd6d34e887e.png" alt="XKCD comic 1739: Fixing Problems" width="312" height="307" /></a></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">غالبًا ما تبدو المشكلات (في الحياة وأيضًا في علوم الكمبيوتر) كبيرة ومخيفة. ولكن إذا واصلنا تقطيعها بعيدًا ، فغالبًا ما يمكننا تقسيمها إلى أجزاء أصغر تافهة بما يكفي لحلها. هذا هو جوهر التفكير التكراري ، وهدفي في هذه المقالة هو تزويدك ، عزيزي القارئ ، بالأدوات المفاهيمية اللازمة للتعامل مع المشكلات من وجهة النظر العودية هذه.</span></p>
<p><span style="font-size: 14pt">معًا ، سنتعلم كيفية التعامل مع العودية في برامج بايثون من خلال إتقان مفاهيم مثل الوظائف العودية وهياكل البيانات العودية. سنتحدث أيضًا عن الحفاظ على الحالة أثناء العودية وتجنب إعادة الحساب عن طريق تخزين النتائج مؤقتًا. هذا سيكون ممتعا جدا. إلى الأمام وإلى الأعلى!</span></p>
<p><span style="font-size: 20pt"><strong>عزيزي سانتا كلوز البيثوني &#8230;</strong></span></p>
<p><span style="font-size: 14pt">أدرك أنه بصفتنا رفقاء في Pythonistas ، نحن جميعًا بالغون موافقون هنا ، لكن يبدو أن الأطفال يستحوذون على جمال التكرار بشكل أفضل. لذا دعونا لا نكون بالغين هنا للحظة ونتحدث عن كيفية استخدام العودية لمساعدة سانتا كلوز.</span></p>
<p><span style="font-size: 14pt">هل تساءلت يومًا كيف يتم تسليم هدايا عيد الميلاد؟ أنا متأكد من ذلك ، وأعتقد أن لدى سانتا كلوز قائمة بالمنازل التي يمر بها. يذهب إلى منزل ، ويسقط الهدايا ، ويأكل البسكويت والحليب ، وينتقل إلى المنزل التالي في القائمة. نظرًا لأن هذه الخوارزمية لتقديم العروض تستند إلى بناء حلقة واضحة ، فإنها تسمى خوارزمية تكرارية.</span></p>
<p><a href="https://files.realpython.com/media/santa_claus_2.ecbf2686f1a1.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/santa_claus_2.ecbf2686f1a1.png" alt="Iterative Present Delivery" width="1812" height="245" /></a></p>
<p><span style="font-size: 14pt">خوارزمية التسليم الحالي التكراري المطبقة في Python:</span></p>
<div class="highlight python">
<pre><code><span class="n">houses</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"Eric's house"</span><span class="p">,</span> <span class="s2">"Kenny's house"</span><span class="p">,</span> <span class="s2">"Kyle's house"</span><span class="p">,</span> <span class="s2">"Stan's house"</span><span class="p">]</span>

<span class="k">def</span> <span class="nf">deliver_presents_iteratively</span><span class="p">():</span>
    <span class="k">for</span> <span class="n">house</span> <span class="ow">in</span> <span class="n">houses</span><span class="p">:</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">"Delivering presents to"</span><span class="p">,</span> <span class="n">house</span><span class="p">)</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">deliver_presents_iteratively</span><span class="p">()</span>
<span class="go">Delivering presents to Eric's house</span>
<span class="go">Delivering presents to Kenny's house</span>
<span class="go">Delivering presents to Kyle's house</span>
<span class="go">Delivering presents to Stan's house</span>
</code></pre>
<p><span style="font-size: 14pt">لكني أشعر بسانتا. في مثل عمره ، لا ينبغي أن يضطر إلى تسليم جميع الهدايا بنفسه. أقترح خوارزمية يمكنه من خلالها تقسيم عمل تقديم الهدايا بين أقزامه:</span></p>
<ol>
<li><span style="font-size: 14pt">تعيين قزم وإعطاء كل العمل له</span></li>
<li><span style="font-size: 14pt">قم بتعيين الألقاب والمسؤوليات إلى الجان بناءً على عدد المنازل المسؤولة عنها:</span><br />
<span style="font-size: 14pt">&gt; 1 هو مدير ويمكنه تعيين اثنين من الجان وتقسيم عمله بينهما</span><br />
<span style="font-size: 14pt">= 1 هو عامل وعليه تسليم الهدايا إلى المنزل المخصص له</span></li>
</ol>
<p><a href="https://files.realpython.com/media/elves_7.8d1af1cd85c8.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/elves_7.8d1af1cd85c8.png" alt="Recursive Present Delivery" width="3837" height="1808" /></a></p>
<p><span style="font-size: 14pt">هذا هو الهيكل النموذجي للخوارزمية العودية. إذا كانت المشكلة الحالية تمثل حالة بسيطة ، قم بحلها. إذا لم يكن الأمر كذلك ، فقم بتقسيمها إلى مشكلات فرعية وطبق نفس الإستراتيجية عليها.</span></p>
<p><span style="font-size: 14pt">الخوارزمية الخاصة بالتسليم الحالي التكراري المطبقة في Python:</span></p>
<div class="highlight python">
<pre><code><span class="n">houses</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"Eric's house"</span><span class="p">,</span> <span class="s2">"Kenny's house"</span><span class="p">,</span> <span class="s2">"Kyle's house"</span><span class="p">,</span> <span class="s2">"Stan's house"</span><span class="p">]</span>

<span class="c1"># Each function call represents an elf doing his work </span>
<span class="k">def</span> <span class="nf">deliver_presents_recursively</span><span class="p">(</span><span class="n">houses</span><span class="p">):</span>
    <span class="c1"># Worker elf doing his work</span>
    <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">houses</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
        <span class="n">house</span> <span class="o">=</span> <span class="n">houses</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">"Delivering presents to"</span><span class="p">,</span> <span class="n">house</span><span class="p">)</span>

    <span class="c1"># Manager elf doing his work</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">mid</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">houses</span><span class="p">)</span> <span class="o">//</span> <span class="mi">2</span>
        <span class="n">first_half</span> <span class="o">=</span> <span class="n">houses</span><span class="p">[:</span><span class="n">mid</span><span class="p">]</span>
        <span class="n">second_half</span> <span class="o">=</span> <span class="n">houses</span><span class="p">[</span><span class="n">mid</span><span class="p">:]</span>

        <span class="c1"># Divides his work among two elves</span>
        <span class="n">deliver_presents_recursively</span><span class="p">(</span><span class="n">first_half</span><span class="p">)</span>
        <span class="n">deliver_presents_recursively</span><span class="p">(</span><span class="n">second_half</span><span class="p">)</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">deliver_presents_recursively</span><span class="p">(</span><span class="n">houses</span><span class="p">)</span>
<span class="go">Delivering presents to Eric's house</span>
<span class="go">Delivering presents to Kenny's house</span>
<span class="go">Delivering presents to Kyle's house</span>
<span class="go">Delivering presents to Stan's house</span>
</code></pre>
<p><strong><span style="font-size: 20pt">الوظائف العودية في بايثون</span></strong></p>
<p><span style="font-size: 14pt">الآن بعد أن أصبح لدينا حدس حول العودية ، دعنا نقدم التعريف الرسمي للدالة العودية. الوظيفة العودية هي وظيفة محددة من حيث نفسها عبر تعبيرات مرجعية ذاتية.</span></p>
<p><span style="font-size: 14pt">هذا يعني أن الوظيفة ستستمر في استدعاء نفسها وتكرار سلوكها حتى يتم استيفاء شرط لإرجاع نتيجة. تشترك جميع الوظائف العودية في بنية مشتركة تتكون من جزأين: الحالة الأساسية والحالة العودية.</span></p>
<p><span style="font-size: 14pt">لتوضيح هذه البنية ، دعنا نكتب دالة عودية لحساب n !:</span></p>
<ol>
<li><span style="font-size: 14pt"><span style="font-size: 14pt">قسّم المشكلة الأصلية إلى حالات أبسط لنفس المشكلة. هذه هي الحالة العودية:<br />
</span></span></p>
<pre><code>n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3 x 2 x 1
n! = n x (n−1)!</code></pre>
</li>
<li><span style="font-size: 14pt"><span style="font-size: 14pt">نظرًا لتقسيم المشكلة الكبيرة إلى مشاكل أقل تعقيدًا على التوالي ، يجب أن تصبح هذه المشكلات الفرعية في النهاية بسيطة جدًا بحيث يمكن حلها دون مزيد من التقسيمات الفرعية. هذه هي الحالة الأساسية:<br />
</span></span></p>
<pre><code>n! = n x (n−1)! 
n! = n x (n−1) x (n−2)!
n! = n x (n−1) x (n−2) x (n−3)!
⋅
⋅
n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3!
n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3 x 2!
n! = n x (n−1) x (n−2) x (n−3) ⋅⋅⋅⋅ x 3 x 2 x 1!</code></pre>
</li>
</ol>
<p><span style="font-size: 14pt">هنا ، 1! هي الحالة الأساسية لدينا ، وهي تساوي 1.</span></p>
<p><span style="font-size: 14pt">دالة تكرارية لحساب ن! تم تنفيذه في Python:</span></p>
<div class="highlight python">
<pre><code><span class="k">def</span> <span class="nf">factorial_recursive</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
    <span class="c1"># Base case: 1! = 1</span>
    <span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">return</span> <span class="mi">1</span>

    <span class="c1"># Recursive case: n! = n * (n-1)!</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">n</span> <span class="o">*</span> <span class="n">factorial_recursive</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">factorial_recursive</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="go">120</span>
</code></pre>
<p><span style="font-size: 14pt">خلف الكواليس ، تضيف كل مكالمة متكررة إطار مكدس (يحتوي على سياق التنفيذ الخاص به) إلى مكدس الاستدعاءات حتى نصل إلى الحالة الأساسية. بعد ذلك ، يبدأ المكدس في التراجع حيث تُرجع كل مكالمة نتائجها:</span></p>
<p><a href="https://files.realpython.com/media/stack.9c4ba62929cf.gif" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block  aligncenter" src="https://files.realpython.com/media/stack.9c4ba62929cf.gif" alt="Call Stack" width="363" height="295" /></a></p>
<p><strong><span style="font-size: 20pt">الحفاظ على الدولة</span></strong></p>
<p><span style="font-size: 14pt">عند التعامل مع الدوال العودية ، ضع في اعتبارك أن كل استدعاء متكرر له سياق تنفيذ خاص به ، لذلك للحفاظ على الحالة أثناء العودية ، عليك إما:</span></p>
<ul>
<li><span style="font-size: 14pt">قم بربط الحالة من خلال كل استدعاء تعاودي بحيث تكون الحالة الحالية جزءًا من سياق تنفيذ المكالمة الحالية</span></li>
<li><span style="font-size: 14pt">حافظ على الدولة في النطاق العالمي</span></li>
</ul>
<p><span style="font-size: 14pt">يجب أن تجعل المظاهرة الأمور أكثر وضوحًا. لنحسب 1 + 2 + 3 ⋅⋅⋅⋅ + 10 باستخدام العودية. الحالة التي يجب أن نحافظ عليها هي (الرقم الحالي الذي نضيفه ، المجموع التراكمي حتى الآن).</span></p>
<p><span style="font-size: 14pt">وإليك كيفية القيام بذلك عن طريق ربطه خلال كل مكالمة متكررة (أي تمرير الحالة الحالية المحدثة إلى كل استدعاء متكرر كوسيطات):</span></p>
<div class="highlight python">
<pre><code><span class="k">def</span> <span class="nf">sum_recursive</span><span class="p">(</span><span class="n">current_number</span><span class="p">,</span> <span class="n">accumulated_sum</span><span class="p">):</span>
    <span class="c1"># Base case</span>
    <span class="c1"># Return the final state</span>
    <span class="k">if</span> <span class="n">current_number</span> <span class="o">==</span> <span class="mi">11</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">accumulated_sum</span>

    <span class="c1"># Recursive case</span>
    <span class="c1"># Thread the state through the recursive call</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">sum_recursive</span><span class="p">(</span><span class="n">current_number</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">accumulated_sum</span> <span class="o">+</span> <span class="n">current_number</span><span class="p">)</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<div class="highlight python repl">
<pre><code><span class="go"># Pass the initial state</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sum_recursive</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">)</span>
<span class="go">55</span>
</code></pre>
</div>
<p><a href="https://files.realpython.com/media/state_3.3e8a68c4fde5.png" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/state_3.3e8a68c4fde5.png" alt="Maintaining State" width="2586" height="889" /></a></p>
<p><span style="font-size: 14pt">إليك كيفية الحفاظ على الدولة من خلال إبقائها في النطاق العالمي:</span></p>
<div class="highlight python">
<pre><code><span class="c1"># Global mutable state</span>
<span class="n">current_number</span> <span class="o">=</span> <span class="mi">1</span>
<span class="n">accumulated_sum</span> <span class="o">=</span> <span class="mi">0</span>


<span class="k">def</span> <span class="nf">sum_recursive</span><span class="p">():</span>
    <span class="k">global</span> <span class="n">current_number</span>
    <span class="k">global</span> <span class="n">accumulated_sum</span>
    <span class="c1"># Base case</span>
    <span class="k">if</span> <span class="n">current_number</span> <span class="o">==</span> <span class="mi">11</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">accumulated_sum</span>
    <span class="c1"># Recursive case</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">accumulated_sum</span> <span class="o">=</span> <span class="n">accumulated_sum</span> <span class="o">+</span> <span class="n">current_number</span>
        <span class="n">current_number</span> <span class="o">=</span> <span class="n">current_number</span> <span class="o">+</span> <span class="mi">1</span>
        <span class="k">return</span> <span class="n">sum_recursive</span><span class="p">()</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">sum_recursive</span><span class="p">()</span>
<span class="go">55</span>
</code></pre>
<p><span style="font-size: 14pt">أفضل ربط الحالة من خلال كل مكالمة متكررة لأنني أجد أن الحالة المتغيرة العالمية شريرة ، لكن هذه مناقشة لوقت لاحق.</span></p>
<p><strong><span style="font-size: 20pt">هياكل البيانات العودية في بايثون</span></strong></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تكون بنية البيانات متكررة إذا كان من الممكن تعريفها من حيث نسخة أصغر من نفسها. القائمة هي مثال على بنية البيانات العودية. اسمحوا لي أن أوضح. افترض أن لديك قائمة فارغة فقط تحت تصرفك ، والعملية الوحيدة التي يمكنك إجراؤها عليها هي:</span></p>
<pre><code><span class="c1"># Return a new list that is the result of</span>
<span class="c1"># adding element to the head (i.e. front) of input_list</span>
<span class="k">def</span> <span class="nf">attach_head</span><span class="p">(</span><span class="n">element</span><span class="p">,</span> <span class="n">input_list</span><span class="p">):</span>
    <span class="k">return</span> <span class="p">[</span><span class="n">element</span><span class="p">]</span> <span class="o">+</span> <span class="n">input_list</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">باستخدام القائمة الفارغة وعملية attach_head ، يمكنك إنشاء أي قائمة. على سبيل المثال ، دعونا ننشئ [1، 46، -31، &#8220;مرحبًا&#8221;]:</span></p>
<div class="highlight python">
<pre><code><span class="n">attach_head</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span>                                                  <span class="c1"># Will return [1, 46, -31, "hello"]</span>
            <span class="n">attach_head</span><span class="p">(</span><span class="mi">46</span><span class="p">,</span>                                     <span class="c1"># Will return [46, -31, "hello"]</span>
                        <span class="n">attach_head</span><span class="p">(</span><span class="o">-</span><span class="mi">31</span><span class="p">,</span>                        <span class="c1"># Will return [-31, "hello"]</span>
                                    <span class="n">attach_head</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">,</span> <span class="p">[]))))</span> <span class="c1"># Will return ["hello"]</span>
</code></pre>
</div>
<div class="highlight">
<pre><code>[1, 46, -31, 'hello']
</code></pre>
</div>
<p><a href="https://files.realpython.com/media/list.3df62a89243d.gif" target="_blank" rel="noopener noreferrer"><img decoding="async" loading="lazy" class="img-fluid mx-auto d-block " src="https://files.realpython.com/media/list.3df62a89243d.gif" alt="Image of a list generated by recursively applying the attach_head  Python function" width="750" height="77" /></a></p>
<ol>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بدءًا بقائمة فارغة ، يمكنك إنشاء أي قائمة عن طريق تطبيق وظيفة attach_head بشكل متكرر ، وبالتالي يمكن تعريف بنية بيانات القائمة بشكل متكرر على النحو التالي:<br />
</span></span></p>
<pre><code>       +---- attach_head(element, smaller list)
list = +
       +---- empty list</code></pre>
</li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يمكن أيضًا اعتبار التكرار على أنه تكوين وظيفة مرجعية ذاتية. نطبق دالة على وسيطة ، ثم نمرر هذه النتيجة كوسيطة لتطبيق آخر لنفس الوظيفة ، وهكذا. تكرار إنشاء attach_head مع نفسها هو نفس استدعاء attach_head لنفسها بشكل متكرر.<br />
</span></li>
</ol>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">القائمة ليست هي بنية البيانات العودية الوحيدة. تشمل الأمثلة الأخرى المجموعة والشجرة والقاموس وما إلى ذلك.</p>
<p>تتوافق هياكل البيانات التكرارية والوظائف التكرارية معًا مثل الخبز والزبدة. غالبًا ما يمكن تصميم بنية الوظيفة العودية بعد تعريف بنية البيانات العودية التي تتخذها كمدخلات. اسمحوا لي أن أوضح ذلك من خلال حساب مجموع كل عناصر القائمة بشكل متكرر:</span></p>
<div class="highlight python">
<pre><code><span class="k">def</span> <span class="nf">list_sum_recursive</span><span class="p">(</span><span class="n">input_list</span><span class="p">):</span>
    <span class="c1"># Base case</span>
    <span class="k">if</span> <span class="n">input_list</span> <span class="o">==</span> <span class="p">[]:</span>
        <span class="k">return</span> <span class="mi">0</span>

    <span class="c1"># Recursive case</span>
    <span class="c1"># Decompose the original problem into simpler instances of the same problem</span>
    <span class="c1"># by making use of the fact that the input is a recursive data structure</span>
    <span class="c1"># and can be deﬁned in terms of a smaller version of itself</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="n">head</span> <span class="o">=</span> <span class="n">input_list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
        <span class="n">smaller_list</span> <span class="o">=</span> <span class="n">input_list</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
        <span class="k">return</span> <span class="n">head</span> <span class="o">+</span> <span class="n">list_sum_recursive</span><span class="p">(</span><span class="n">smaller_list</span><span class="p">)</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">list_sum_recursive</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">])</span>
<span class="go">6</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">التكرار الساذج هو ساذج</span></strong></p>
<p>تم تحديد أرقام فيبوناتشي في الأصل من قبل عالم الرياضيات الإيطالي فيبوناتشي في القرن الثالث عشر لنمذجة نمو مجموعات الأرانب. توقع فيبوناتشي أن عدد أزواج الأرانب المولودين في سنة معينة يساوي عدد أزواج الأرانب التي ولدت في كل عام من العامين السابقين ، بدءًا من زوج واحد من الأرانب في السنة الأولى.</p>
<p>لحساب عدد الأرانب التي ولدت في السنة التاسعة ، حدد علاقة التكرار:</span></p>
<pre>F<sub>n</sub> = F<sub>n-1</sub> + F<sub>n-2</sub></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الحالات الأساسية هي:</span></p>
<pre>F<sub>0</sub> = 0 and F<sub>1</sub> = 1</pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">دعونا نكتب دالة تعاودية لحساب رقم فيبوناتشي التاسع:</span></p>
<div class="highlight python">
<pre><code><span class="k">def</span> <span class="nf">fibonacci_recursive</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">"Calculating F"</span><span class="p">,</span> <span class="s2">"("</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="s2">")"</span><span class="p">,</span> <span class="n">sep</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">", "</span><span class="p">)</span>

    <span class="c1"># Base case</span>
    <span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="mi">0</span>
    <span class="k">elif</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">return</span> <span class="mi">1</span>

    <span class="c1"># Recursive case</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">fibonacci_recursive</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">fibonacci_recursive</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">fibonacci_recursive</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="go">Calculating F(5), Calculating F(4), Calculating F(3), Calculating F(2), Calculating F(1), </span>
<span class="go">Calculating F(0), Calculating F(1), Calculating F(2), Calculating F(1), Calculating F(0), </span>
<span class="go">Calculating F(3), Calculating F(2), Calculating F(1), Calculating F(0), Calculating F(1),</span>

<span class="go">5</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كان اتباع التعريف العودي لعدد فيبوناتشي التاسع غير فعال إلى حد ما. كما ترى من المخرجات أعلاه ، نحن نعيد حساب القيم دون داع. دعونا نحاول تحسين fibonacci_recursive عن طريق التخزين المؤقت لنتائج كل حساب Fibonacci Fk:</span></p>
<div class="highlight python">
<pre><code><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">lru_cache</span>

<span class="nd">@lru_cache</span><span class="p">(</span><span class="n">maxsize</span><span class="o">=</span><span class="kc">None</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">fibonacci_recursive</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">"Calculating F"</span><span class="p">,</span> <span class="s2">"("</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="s2">")"</span><span class="p">,</span> <span class="n">sep</span><span class="o">=</span><span class="s2">""</span><span class="p">,</span> <span class="n">end</span><span class="o">=</span><span class="s2">", "</span><span class="p">)</span>

    <span class="c1"># Base case</span>
    <span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="mi">0</span>
    <span class="k">elif</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
        <span class="k">return</span> <span class="mi">1</span>

    <span class="c1"># Recursive case</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="n">fibonacci_recursive</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="n">fibonacci_recursive</span><span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span>
</code></pre>
</div>
<div class="highlight python repl"></div>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">fibonacci_recursive</span><span class="p">(</span><span class="mi">5</span><span class="p">)</span>
<span class="go">Calculating F(5), Calculating F(4), Calculating F(3), Calculating F(2), Calculating F(1), Calculating F(0),</span>

<span class="go">5</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">lru_cache هو مصمم يقوم بتخزين النتائج مؤقتًا. وبالتالي ، نتجنب إعادة الحساب عن طريق التحقق صراحة من القيمة قبل محاولة حسابها. شيء واحد يجب مراعاته حول lru_cache هو أنه نظرًا لأنه يستخدم قاموسًا لتخزين النتائج مؤقتًا ، يجب أن تكون الوسيطات الموضعية والكلمات الرئيسية (التي تعمل كمفاتيح في هذا القاموس) للوظيفة قابلة للتجزئة.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">تفاصيل مزعجة</span></strong></p>
<p>بايثون ليس لديها دعم لإلغاء استدعاء الذيل. نتيجة لذلك ، يمكن أن تتسبب في تجاوز مكدس إذا انتهى بك الأمر باستخدام إطارات مكدس أكثر من عمق مكدس الاستدعاءات الافتراضي:</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">getrecursionlimit</span><span class="p">()</span>
<span class="go">3000</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ضع هذا القيد في الاعتبار إذا كان لديك برنامج يتطلب تكرارًا عميقًا.</p>
<p>أيضًا ، لا تدعم هياكل البيانات القابلة للتغيير في Python المشاركة الهيكلية ، لذا فإن معاملتها مثل هياكل البيانات غير القابلة للتغيير ستؤثر سلبًا على مساحتك وكفاءة GC (جمع البيانات المهملة) لأنك ستنتهي بدون داعٍ إلى نسخ الكثير من الكائنات القابلة للتغيير. على سبيل المثال ، لقد استخدمت هذا النمط لتحليل القوائم والتكرار عليها:</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="n">input_list</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">head</span> <span class="o">=</span> <span class="n">input_list</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">tail</span> <span class="o">=</span> <span class="n">input_list</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="s2">"head --"</span><span class="p">,</span> <span class="n">head</span><span class="p">)</span>
<span class="go">head -- 1</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">print</span><span class="p">(</span><span class="s2">"tail --"</span><span class="p">,</span> <span class="n">tail</span><span class="p">)</span>
<span class="go">tail -- [2, 3]</span>
</code></pre>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">فعلت ذلك لتبسيط الأمور من أجل الوضوح. ضع في اعتبارك أن الذيل يتم إنشاؤه عن طريق النسخ. يمكن أن يؤثر القيام بذلك بشكل متكرر على قوائم كبيرة سلبًا على مساحتك وكفاءة GC.</p>
<p><strong><span style="font-size: 20pt">زعنفة</span></strong></p>
<p>طُلب مني ذات مرة شرح العودية في مقابلة. أخذت ورقة وكتبت من فضلك اقلبها على كلا الجانبين. لم يستوعب القائم بإجراء المقابلة الدعابة ، ولكن الآن بعد أن قرأت هذا المقال ، أتمنى أن تفعل 🙂 Happy Pythoning!<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">المراجع</span></strong><br />
</span></p>
<ol>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">التفكير التكراري<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">المخادع الصغير<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">مفاهيم وتقنيات ونماذج برمجة الحاسوب<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">دليل تصميم الخوارزمية<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">برمجة هاسكل من المبادئ الأولى</span></li>
</ol>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d8%a7%d9%84%d8%aa%d9%81%d9%83%d9%8a%d8%b1-%d8%a7%d9%84%d8%aa%d9%83%d8%b1%d8%a7%d8%b1%d9%8a-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/">التفكير التكراري في بايثون</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://arabdars.com/%d8%a7%d9%84%d8%aa%d9%81%d9%83%d9%8a%d8%b1-%d8%a7%d9%84%d8%aa%d9%83%d8%b1%d8%a7%d8%b1%d9%8a-%d9%81%d9%8a-%d8%a8%d8%a7%d9%8a%d8%ab%d9%88%d9%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>ما هو قفل مترجم Python العالمي (GIL)؟</title>
		<link>https://arabdars.com/%d9%85%d8%a7-%d9%87%d9%88-%d9%82%d9%81%d9%84-%d9%85%d8%aa%d8%b1%d8%ac%d9%85-python-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85%d9%8a-gil%d8%9f/</link>
					<comments>https://arabdars.com/%d9%85%d8%a7-%d9%87%d9%88-%d9%82%d9%81%d9%84-%d9%85%d8%aa%d8%b1%d8%ac%d9%85-python-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85%d9%8a-gil%d8%9f/#respond</comments>
		
		<dc:creator><![CDATA[Reyhane]]></dc:creator>
		<pubDate>Wed, 16 Sep 2020 15:35:30 +0000</pubDate>
				<category><![CDATA[الماتلاب Matlab]]></category>
		<guid isPermaLink="false">https://arabdars.com/?p=1608</guid>

					<description><![CDATA[<p>جدول المحتويات ما المشكلة التي حلها GIL لبايثون؟ لماذا تم اختيار GIL كحل؟ التأثير على برامج بايثون متعددة الخيوط لماذا لم تتم إزالة GIL حتى الآن؟ لماذا لم تتم إزالته في Python 3؟ كيفية التعامل مع Python’s GIL إن قفل Python Global Interpreter Lock أو GIL ، بكلمات بسيطة ، هو كائن المزامنة (أو القفل) [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d9%85%d8%a7-%d9%87%d9%88-%d9%82%d9%81%d9%84-%d9%85%d8%aa%d8%b1%d8%ac%d9%85-python-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85%d9%8a-gil%d8%9f/">ما هو قفل مترجم Python العالمي (GIL)؟</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">جدول المحتويات</span></strong><br />
</span></p>
<ul style="text-align: justify">
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">ما المشكلة التي حلها GIL لبايثون؟<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لماذا تم اختيار GIL كحل؟<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">التأثير على برامج بايثون متعددة الخيوط<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لماذا لم تتم إزالة GIL حتى الآن؟<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لماذا لم تتم إزالته في Python 3؟<br />
</span></li>
<li><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كيفية التعامل مع Python’s GIL<br />
</span></li>
</ul>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">إن قفل Python Global Interpreter Lock أو GIL ، بكلمات بسيطة ، هو كائن المزامنة (أو القفل) الذي يسمح لخيط واحد فقط بالسيطرة على مترجم Python.</p>
<p>هذا يعني أن مؤشر ترابط واحد فقط يمكن أن يكون في حالة تنفيذ في أي وقت. لا يكون تأثير GIL مرئيًا للمطورين الذين ينفذون برامج أحادية السلسلة ، ولكن يمكن أن يكون عقبة في الأداء في التعليمات البرمجية المرتبطة بوحدة المعالجة المركزية والمتعددة المسارات.</p>
<p>نظرًا لأن GIL يسمح فقط بتنفيذ مؤشر ترابط واحد في كل مرة حتى في بنية متعددة الخيوط مع أكثر من نواة وحدة المعالجة المركزية ، فقد اكتسب GIL سمعة باعتباره ميزة &#8220;سيئة السمعة&#8221; في Python.</p>
<p>ستتعرف في هذه المقالة على كيفية تأثير GIL على أداء برامج Python الخاصة بك ، وكيف يمكنك التخفيف من التأثير الذي قد يحدثه على التعليمات البرمجية الخاصة بك.</p>
<p><strong><span style="font-size: 20pt">ما المشكلة التي حلها GIL لبايثون؟</span></strong></p>
<p>يستخدم Python حساب المرجع لإدارة الذاكرة. هذا يعني أن الكائنات التي تم إنشاؤها في Python لها متغير عدد مرجعي يتتبع عدد المراجع التي تشير إلى الكائن. عندما يصل هذا العدد إلى الصفر ، يتم تحرير الذاكرة التي يشغلها الكائن.</p>
<p>دعنا نلقي نظرة على مثال رمز مختصر لشرح كيفية عمل العد المرجعي:</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">a</span> <span class="o">=</span> <span class="p">[]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">b</span> <span class="o">=</span> <span class="n">a</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">getrefcount</span><span class="p">(</span><span class="n">a</span><span class="p">)</span>
<span class="go">3</span>
</code></pre>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في المثال أعلاه ، كان عدد المراجع لكائن القائمة الفارغة [] هو 3. تمت الإشارة إلى كائن القائمة بواسطة a و b وتم تمرير الوسيطة إلى sys.getrefcount ().</p>
<p>العودة إلى GIL:</p>
<p>كانت المشكلة أن متغير العد المرجعي هذا يحتاج إلى الحماية من ظروف السباق حيث يزيد خيطان قيمته أو ينقصان في وقت واحد. إذا حدث هذا ، فقد يتسبب في حدوث تسرب للذاكرة التي لم يتم إصدارها مطلقًا ، أو الأسوأ من ذلك ، تحرير الذاكرة بشكل غير صحيح بينما لا تزال الإشارة إلى هذا الكائن موجودة. يمكن أن يتسبب هذا في حدوث أعطال أو أخطاء أخرى &#8220;غريبة&#8221; في برامج بايثون.</p>
<p>يمكن الحفاظ على متغير عدد المرجع هذا آمنًا عن طريق إضافة أقفال إلى جميع هياكل البيانات المشتركة عبر سلاسل الرسائل بحيث لا يتم تعديلها بشكل غير متسق.</p>
<p>لكن إضافة قفل لكل كائن أو مجموعة من الكائنات يعني وجود أقفال متعددة والتي يمكن أن تسبب مشكلة أخرى &#8211; Deadlocks (يمكن أن تحدث حالات التوقف التام فقط إذا كان هناك أكثر من قفل واحد). يتمثل أحد الآثار الجانبية الأخرى في انخفاض الأداء الناجم عن الاستحواذ المتكرر وإطلاق الأقفال.</p>
<p>GIL هو قفل واحد على المترجم الفوري نفسه والذي يضيف قاعدة مفادها أن تنفيذ أي كود بايت Python يتطلب الحصول على قفل المترجم الفوري. هذا يمنع حالات الجمود (حيث لا يوجد سوى قفل واحد) ولا يقدم الكثير من الأداء الزائد. لكنه يجعل أي برنامج Python مرتبط بوحدة المعالجة المركزية مترابطًا بشكل فعال.</p>
<p>على الرغم من استخدام GIL من قبل المترجمين الفوريين للغات أخرى مثل Ruby ، ​​إلا أنه ليس الحل الوحيد لهذه المشكلة. تتجنب بعض اللغات مطلب GIL لإدارة الذاكرة الآمنة باستخدام طرق أخرى غير حساب المرجع ، مثل جمع البيانات المهملة.</p>
<p>من ناحية أخرى ، هذا يعني أنه يتعين على هذه اللغات في كثير من الأحيان تعويض فقدان مزايا الأداء المترابط الفردي لـ GIL عن طريق إضافة ميزات أخرى لتعزيز الأداء مثل مترجمي JIT.<br />
</span></p>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><span style="font-size: 20pt"><strong>لماذا تم اختيار GIL كحل؟</strong></span></p>
<p>إذن ، لماذا تم استخدام أسلوب يبدو أنه يعيق استخدام لغة بايثون؟ هل كان قرارًا سيئًا من قِبل مطوري Python؟</p>
<p>حسنًا ، على حد تعبير لاري هاستينغز ، فإن قرار تصميم GIL هو أحد الأشياء التي جعلت بايثون مشهورة كما هي اليوم.</p>
<p>كانت Python موجودة منذ الأيام التي لم يكن لدى أنظمة التشغيل فيها مفهوم الخيوط. تم تصميم Python ليكون سهل الاستخدام من أجل جعل التطوير أسرع وبدأ المزيد والمزيد من المطورين في استخدامه.</p>
<p>تمت كتابة الكثير من الإضافات لمكتبات C الحالية التي كانت هناك حاجة إلى ميزاتها في Python. لمنع التغييرات غير المتسقة ، تتطلب امتدادات C هذه إدارة ذاكرة آمنة للخيط والتي قدمها GIL.</p>
<p>GIL سهل التنفيذ ويمكن إضافته بسهولة إلى Python. إنه يوفر زيادة في أداء البرامج أحادية الخيوط حيث يلزم إدارة قفل واحد فقط.</p>
<p>أصبح من السهل دمج مكتبات C التي لم تكن آمنة بمؤشر الترابط. وأصبحت امتدادات C هذه أحد الأسباب التي جعلت المجتمعات المختلفة تتبنى لغة Python بسهولة.</p>
<p>كما ترى ، كان GIL حلاً عمليًا لمشكلة صعبة واجهها مطورو CPython في وقت مبكر من حياة Python.</p>
<p><span style="font-size: 20pt"><strong>التأثير على برامج بايثون متعددة الخيوط</strong></span></p>
<p>عندما تنظر إلى برنامج Python نموذجي &#8211; أو أي برنامج كمبيوتر لهذا الأمر &#8211; هناك فرق بين تلك المرتبطة بوحدة المعالجة المركزية في أدائها وتلك المرتبطة بـ I / O.</p>
<p>البرامج المرتبطة بوحدة المعالجة المركزية هي تلك البرامج التي تدفع وحدة المعالجة المركزية إلى أقصى حدودها. يتضمن ذلك البرامج التي تقوم بحسابات رياضية مثل مضاعفات المصفوفات والبحث ومعالجة الصور وما إلى ذلك.</span></p>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">البرامج المرتبطة بـ I / O هي تلك التي تقضي وقتًا في انتظار الإدخال / الإخراج الذي يمكن أن يأتي من مستخدم ، أو ملف ، أو قاعدة بيانات ، أو شبكة ، وما إلى ذلك. تضطر البرامج المرتبطة بـ I / O أحيانًا إلى الانتظار لفترة طويلة من الوقت حتى يتم الحصول على ما يحتاجون إليه من المصدر نظرًا لحقيقة أن المصدر قد يحتاج إلى القيام بمعالجته الخاصة قبل أن يصبح الإدخال / الإخراج جاهزًا ، على سبيل المثال ، يفكر المستخدم فيما يجب إدخاله في موجه إدخال أو استعلام قاعدة بيانات قيد التشغيل في العملية الخاصة.</p>
<p>دعنا نلقي نظرة على برنامج بسيط مرتبط بوحدة المعالجة المركزية يقوم بإجراء عد تنازلي:</span></p>
<pre><code><span class="c1"># single_threaded.py</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">from</span> <span class="nn">threading</span> <span class="kn">import</span> <span class="n">Thread</span>

<span class="n">COUNT</span> <span class="o">=</span> <span class="mi">50000000</span>

<span class="k">def</span> <span class="nf">countdown</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
    <span class="k">while</span> <span class="n">n</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">:</span>
        <span class="n">n</span> <span class="o">-=</span> <span class="mi">1</span>

<span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="n">countdown</span><span class="p">(</span><span class="n">COUNT</span><span class="p">)</span>
<span class="n">end</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>

<span class="nb">print</span><span class="p">(</span><span class="s1">'Time taken in seconds -'</span><span class="p">,</span> <span class="n">end</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span>
</code></pre>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">أعطى تشغيل هذا الكود على نظامي باستخدام 4 مراكز الإخراج التالي:</span></p>
<pre><code><span class="gp">$</span> python single_threaded.py
<span class="go">Time taken in seconds - 6.20024037361145</span>
</code></pre>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الآن قمت بتعديل الكود قليلاً لأفعله لنفس العد التنازلي باستخدام خيطين متوازيين:</span></p>
<pre><code><span class="c1"># multi_threaded.py</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="kn">from</span> <span class="nn">threading</span> <span class="kn">import</span> <span class="n">Thread</span>

<span class="n">COUNT</span> <span class="o">=</span> <span class="mi">50000000</span>

<span class="k">def</span> <span class="nf">countdown</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
    <span class="k">while</span> <span class="n">n</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">:</span>
        <span class="n">n</span> <span class="o">-=</span> <span class="mi">1</span>

<span class="n">t1</span> <span class="o">=</span> <span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">countdown</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">COUNT</span><span class="o">//</span><span class="mi">2</span><span class="p">,))</span>
<span class="n">t2</span> <span class="o">=</span> <span class="n">Thread</span><span class="p">(</span><span class="n">target</span><span class="o">=</span><span class="n">countdown</span><span class="p">,</span> <span class="n">args</span><span class="o">=</span><span class="p">(</span><span class="n">COUNT</span><span class="o">//</span><span class="mi">2</span><span class="p">,))</span>

<span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="n">t1</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">t2</span><span class="o">.</span><span class="n">start</span><span class="p">()</span>
<span class="n">t1</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
<span class="n">t2</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
<span class="n">end</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>

<span class="nb">print</span><span class="p">(</span><span class="s1">'Time taken in seconds -'</span><span class="p">,</span> <span class="n">end</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span>
</code></pre>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">وعندما قمت بتشغيله مرة أخرى:<br />
</span></p>
<pre><code><span class="gp">$</span> python multi_threaded.py
<span class="go">Time taken in seconds - 6.924342632293701</span>
</code></pre>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كما ترى ، يستغرق كلا الإصدارين نفس القدر من الوقت تقريبًا للانتهاء. في الإصدار متعدد الخيوط ، منع GIL الخيوط المرتبطة بوحدة المعالجة المركزية من التنفيذ في parellel.</p>
<p>لا يؤثر GIL كثيرًا على أداء البرامج متعددة مؤشرات الترابط المرتبطة بالإدخال / الإخراج حيث تتم مشاركة القفل بين مؤشرات الترابط أثناء انتظار الإدخال / الإخراج.</p>
<p>لكن البرنامج الذي تكون خيوطه مرتبطة تمامًا بوحدة المعالجة المركزية ، على سبيل المثال ، البرنامج الذي يعالج صورة في أجزاء باستخدام خيوط ، لن يصبح فقط مترابطًا واحدًا بسبب القفل ولكنه سيشهد أيضًا زيادة في وقت التنفيذ ، كما هو موضح في المثال أعلاه ، مقارنةً بالسيناريو حيث تمت كتابته ليكون متسلسلًا بالكامل.</p>
<p>هذه الزيادة هي نتيجة اكتساب وإطلاق النفقات العامة المضافة بواسطة القفل.<br />
</span></p>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">لماذا لم تتم إزالة GIL حتى الآن؟</span></strong></p>
<p>يتلقى مطورو Python الكثير من الشكاوى بخصوص هذا ، لكن لغة شائعة مثل Python لا يمكنها إحداث تغيير مهم مثل إزالة GIL دون التسبب في مشاكل عدم التوافق مع الإصدارات السابقة.</p>
<p>من الواضح أنه يمكن إزالة GIL وقد تم القيام بذلك عدة مرات في الماضي من قبل المطورين والباحثين ولكن كل هذه المحاولات كسرت امتدادات C الحالية التي تعتمد بشكل كبير على الحل الذي توفره GIL.</p>
<p>بالطبع ، هناك حلول أخرى للمشكلة التي يحلها GIL ولكن بعضها يقلل من أداء برامج الإدخال / الإخراج ذات الخيوط المفردة والمتعددة الخيوط وبعضها صعب للغاية. بعد كل شيء ، لا تريد أن تعمل برامج Python الحالية بشكل أبطأ بعد ظهور إصدار جديد ، أليس كذلك؟</p>
<p>أعطى مبتكر Python و BDFL ، Guido van Rossum ، إجابة للمجتمع في سبتمبر 2007 في مقالته &#8220;ليس من السهل إزالة GIL&#8221;:<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">&#8220;أرحب بمجموعة من التصحيحات في Py3k فقط إذا لم ينخفض ​​أداء برنامج أحادي السلسلة (وبرنامج متعدد الخيوط ولكن مرتبط بإدخال / إخراج)&#8221;</span></p></blockquote>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">وهذا الشرط لم يتم الوفاء به بأي من المحاولات التي تمت منذ ذلك الحين.</p>
<p><strong><span style="font-size: 20pt">لماذا لم تتم إزالته في Python 3؟</span></strong></p>
<p>حصلت Python 3 على فرصة لبدء الكثير من الميزات من البداية ، وفي هذه العملية ، حطمت بعض امتدادات C الحالية التي تطلبت بعد ذلك التغييرات ليتم تحديثها ونقلها للعمل مع Python 3. وهذا هو السبب في أن الإصدارات المبكرة من شهدت Python 3 اعتمادًا أبطأ من قبل المجتمع.</p>
<p>ولكن لماذا لم يتم إزالة GIL جنبًا إلى جنب؟</p>
<p>كان من الممكن أن تؤدي إزالة GIL إلى جعل Python 3 أبطأ مقارنةً بـ Python 2 في الأداء أحادي السلسلة ويمكنك تخيل ما كان سينتج عنه. لا يمكنك المجادلة مع مزايا الأداء أحادية السلسلة لـ GIL. وبالتالي فإن النتيجة هي أن Python 3 لا يزال لديه GIL.</p>
<p>لكن Python 3 جلبت تحسينًا كبيرًا على GIL الحالي &#8211;</p>
<p>ناقشنا تأثير GIL على البرامج متعددة الخيوط &#8220;المرتبطة فقط بوحدة المعالجة المركزية&#8221; و &#8220;I / O فقط&#8221; ولكن ماذا عن البرامج التي تكون فيها بعض سلاسل العمليات مرتبطة بـ I / O وبعضها مرتبط بوحدة المعالجة المركزية؟</p>
<p>في مثل هذه البرامج ، عُرف عن Python&#8217;s GIL بتجويع سلاسل الإدخال / الإخراج من خلال عدم منحها فرصة للحصول على GIL من سلاسل العمليات المرتبطة بوحدة المعالجة المركزية.</p>
<p>كان هذا بسبب آلية مدمجة في Python أجبرت الخيوط على تحرير GIL بعد فترة زمنية ثابتة من الاستخدام المتواصل وإذا لم يحصل أي شخص آخر على GIL ، فيمكن لنفس الخيط مواصلة استخدامه.</span></p>
<pre><code><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="c1"># The interval is set to 100 instructions:</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">getcheckinterval</span><span class="p">()</span>
<span class="go">100</span>
</code></pre>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كانت المشكلة في هذه الآلية هي أن الخيط المرتبط بوحدة المعالجة المركزية في معظم الأحيان سوف يستعيد GIL نفسه قبل أن تتمكن الخيوط الأخرى من الحصول عليه. تم البحث عن هذا بواسطة David Beazley ويمكن العثور على التصورات هنا.</p>
<p>تم إصلاح هذه المشكلة في Python 3.2 في عام 2009 من قبل Antoine Pitrou الذي أضاف آلية للنظر في عدد طلبات الاستحواذ على GIL من خلال مؤشرات الترابط الأخرى التي تم إسقاطها وعدم السماح للخيط الحالي بإعادة الحصول على GIL قبل أن تحصل الخيوط الأخرى على فرصة للتشغيل.<br />
</span></p>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">كيفية التعامل مع Python’s GIL</span></strong></p>
<p>إذا كان GIL يسبب لك مشكلات ، فإليك بعض الطرق التي يمكنك تجربتها:</p>
<p>المعالجة المتعددة مقابل خيوط المعالجة المتعددة: الطريقة الأكثر شيوعًا هي استخدام نهج المعالجة المتعددة حيث تستخدم عمليات متعددة بدلاً من الخيوط. تحصل كل عملية من عمليات Python على مترجم Python الخاص بها ومساحة للذاكرة حتى لا يمثل GIL مشكلة. تحتوي Python على وحدة معالجة متعددة تتيح لنا إنشاء عمليات بسهولة مثل هذا:</span></p>
<pre><code><span class="kn">from</span> <span class="nn">multiprocessing</span> <span class="kn">import</span> <span class="n">Pool</span>
<span class="kn">import</span> <span class="nn">time</span>

<span class="n">COUNT</span> <span class="o">=</span> <span class="mi">50000000</span>
<span class="k">def</span> <span class="nf">countdown</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
    <span class="k">while</span> <span class="n">n</span><span class="o">&gt;</span><span class="mi">0</span><span class="p">:</span>
        <span class="n">n</span> <span class="o">-=</span> <span class="mi">1</span>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">'__main__'</span><span class="p">:</span>
    <span class="n">pool</span> <span class="o">=</span> <span class="n">Pool</span><span class="p">(</span><span class="n">processes</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
    <span class="n">start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
    <span class="n">r1</span> <span class="o">=</span> <span class="n">pool</span><span class="o">.</span><span class="n">apply_async</span><span class="p">(</span><span class="n">countdown</span><span class="p">,</span> <span class="p">[</span><span class="n">COUNT</span><span class="o">//</span><span class="mi">2</span><span class="p">])</span>
    <span class="n">r2</span> <span class="o">=</span> <span class="n">pool</span><span class="o">.</span><span class="n">apply_async</span><span class="p">(</span><span class="n">countdown</span><span class="p">,</span> <span class="p">[</span><span class="n">COUNT</span><span class="o">//</span><span class="mi">2</span><span class="p">])</span>
    <span class="n">pool</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
    <span class="n">pool</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
    <span class="n">end</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
    <span class="nb">print</span><span class="p">(</span><span class="s1">'Time taken in seconds -'</span><span class="p">,</span> <span class="n">end</span> <span class="o">-</span> <span class="n">start</span><span class="p">)</span>
</code></pre>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">أعطى تشغيل هذا على نظامي هذا الناتج:</span></p>
<pre><code><span class="gp">$</span> python multiprocess.py
<span class="go">Time taken in seconds - 4.060242414474487</span>
</code></pre>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">زيادة جيدة في الأداء مقارنة بالإصدار متعدد الخيوط ، أليس كذلك؟</span></p>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">لم ينخفض ​​الوقت إلى نصف ما رأيناه أعلاه لأن إدارة العملية لها نفقاتها العامة الخاصة. تعد العمليات المتعددة أثقل من الخيوط المتعددة ، لذا ضع في اعتبارك أن هذا قد يصبح عنق زجاجة.</p>
<p>مفسرات بايثون البديلة: لدى بايثون تطبيقات متعددة للمترجمين الفوريين. CPython و Jython و IronPython و PyPy ، المكتوبة بلغة C و Java و C # و Python على التوالي ، هي الأكثر شيوعًا. يوجد GIL فقط في تطبيق Python الأصلي وهو CPython. إذا كان برنامجك ومكتباته متاحًا لأحد التطبيقات الأخرى ، فيمكنك تجربتها أيضًا.</p>
<p>ما عليك سوى الانتظار: بينما يستفيد العديد من مستخدمي Python من مزايا الأداء الفردي لـ GIL. لا يضطر المبرمجون متعددو الخيوط إلى القلق لأن بعض ألمع العقول في مجتمع Python يعملون على إزالة GIL من CPython. تُعرف إحدى هذه المحاولات باسم استئصال جيلكتوم.</p>
<p>غالبًا ما يُنظر إلى Python GIL على أنه موضوع غامض وصعب. لكن ضع في اعتبارك أنه بصفتك Pythonista ، فأنت عادةً ما تتأثر بها فقط إذا كنت تكتب امتدادات C أو إذا كنت تستخدم خيوط المعالجة المتعددة المرتبطة بوحدة المعالجة المركزية في برامجك.</p>
<p>في هذه الحالة ، يجب أن توفر لك هذه المقالة كل ما تحتاجه لفهم ماهية GIL وكيفية التعامل معها في مشاريعك الخاصة. وإذا كنت تريد فهم الأعمال الداخلية منخفضة المستوى لـ GIL ، فإنني أوصيك بمشاهدة حديث Understanding the Python GIL لـ David Beazley.</span></p>
<p>The post <a rel="nofollow" href="https://arabdars.com/%d9%85%d8%a7-%d9%87%d9%88-%d9%82%d9%81%d9%84-%d9%85%d8%aa%d8%b1%d8%ac%d9%85-python-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85%d9%8a-gil%d8%9f/">ما هو قفل مترجم Python العالمي (GIL)؟</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://arabdars.com/%d9%85%d8%a7-%d9%87%d9%88-%d9%82%d9%81%d9%84-%d9%85%d8%aa%d8%b1%d8%ac%d9%85-python-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85%d9%8a-gil%d8%9f/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>8 شركات برمجيات من الطراز العالمي تستخدم بايثون</title>
		<link>https://arabdars.com/8-%d8%b4%d8%b1%d9%83%d8%a7%d8%aa-%d8%a8%d8%b1%d9%85%d8%ac%d9%8a%d8%a7%d8%aa-%d9%85%d9%86-%d8%a7%d9%84%d8%b7%d8%b1%d8%a7%d8%b2-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85%d9%8a-%d8%aa%d8%b3%d8%aa%d8%ae%d8%af/</link>
					<comments>https://arabdars.com/8-%d8%b4%d8%b1%d9%83%d8%a7%d8%aa-%d8%a8%d8%b1%d9%85%d8%ac%d9%8a%d8%a7%d8%aa-%d9%85%d9%86-%d8%a7%d9%84%d8%b7%d8%b1%d8%a7%d8%b2-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85%d9%8a-%d8%aa%d8%b3%d8%aa%d8%ae%d8%af/#respond</comments>
		
		<dc:creator><![CDATA[Reyhane]]></dc:creator>
		<pubDate>Wed, 16 Sep 2020 14:50:04 +0000</pubDate>
				<category><![CDATA[الماتلاب Matlab]]></category>
		<guid isPermaLink="false">https://arabdars.com/?p=1605</guid>

					<description><![CDATA[<p>جدول المحتويات الضوء الصناعي والسحر جوجل موقع التواصل الاجتماعي الفيسبوك انستغرام سبوتيفي كورا نيتفليكس بصندوق الإسقاط رديت اي شخص اخر؟ هناك أكثر من 500 لغة برمجة حالية ، مع كتابة المزيد كل يوم. من المسلم به أن غالبية هذه التداخلات ولم يكن من المفترض أبدًا استخدام عدد كبير خارج إطار نظري أو معمل. ولكن بالنسبة [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://arabdars.com/8-%d8%b4%d8%b1%d9%83%d8%a7%d8%aa-%d8%a8%d8%b1%d9%85%d8%ac%d9%8a%d8%a7%d8%aa-%d9%85%d9%86-%d8%a7%d9%84%d8%b7%d8%b1%d8%a7%d8%b2-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85%d9%8a-%d8%aa%d8%b3%d8%aa%d8%ae%d8%af/">8 شركات برمجيات من الطراز العالمي تستخدم بايثون</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">جدول المحتويات</span></strong><br />
</span></p>
<ul>
<li style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">الضوء الصناعي والسحر<br />
</span></li>
<li style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">جوجل<br />
</span></li>
<li style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">موقع التواصل الاجتماعي الفيسبوك<br />
</span></li>
<li style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">انستغرام<br />
</span></li>
<li style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">سبوتيفي<br />
</span></li>
<li style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كورا<br />
</span></li>
<li style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">نيتفليكس<br />
</span></li>
<li style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">بصندوق الإسقاط<br />
</span></li>
<li style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">رديت<br />
</span></li>
<li style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">اي شخص اخر؟<br />
</span></li>
</ul>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">هناك أكثر من 500 لغة برمجة حالية ، مع كتابة المزيد كل يوم. من المسلم به أن غالبية هذه التداخلات ولم يكن من المفترض أبدًا استخدام عدد كبير خارج إطار نظري أو معمل. ولكن بالنسبة للغات البرمجة المستخدمة في الترميز اليومي والأعمال التجارية ، عليك أن تختار. ما اللغات التي يجب أن تتعلمها ، ولماذا تستثمر وقتك في تعلمها؟</p>
<p>نظرًا لأن هذا موقع مخصص لـ Python ، فقد أخبرناك بالفعل لماذا تعتبر Python لغة رائعة يجب تعلمها. وربما تعرف كيف أن Python هي على الأرجح اللغة المفضلة لـ Raspberry Pi (حيث تأتي معظمها محملة مسبقًا بها). ومعرفة ذلك ، فأنت تعرف ما هي الأشياء المدهشة التي يمكنك القيام بها باستخدام مجموعة Pi وقليل من البراعة. في حين أنه من السهل أن ترى كيف يمكنك العبث ببايثون ، فقد تتساءل عن كيفية ترجمة ذلك إلى تطبيقات الأعمال الواقعية وتطبيقات العالم الحقيقي.</p>
<p>ما سنفعله الآن هو إخبارك عن ثماني شركات من الدرجة الأولى تعرف أنها تستخدم بايثون. بهذه الطريقة يمكنك أن ترى ما هي فرص العالم الحقيقي العظيمة المتاحة لمطوري بايثون هناك.</p>
<p><strong><span style="font-size: 20pt">الضوء الصناعي والسحر</span></strong></p>
<p>Industrial Light and Magic (ILM) هي قوة المؤثرات الخاصة التي أسسها جورج لوكاس في عام 1975 لإنشاء FX لـ Star Wars. منذ ذلك الحين ، أصبحوا مرادفين لـ FX ، حيث فازوا بجوائز متعددة لعملهم في الأفلام والإعلانات التجارية.</p>
<p>ركزت ILM في أيامها الأولى على التأثيرات العملية ، لكنها سرعان ما أدركت أن التأثيرات الناتجة عن الكمبيوتر هي مستقبل العملات الأجنبية بشكل عام. تأسس قسم CGI في عام 1979 وكان أول تأثير له هو تسلسل انفجار مشروع Genesis في Star Trek II: The Wrath of Khan.</p>
<p>في الأصل ، كان استوديو CGI التابع لـ ILM يعمل خارج غلاف Unix ، ولكن هذا كان يتعامل مع قدر ضئيل نسبيًا من العمل. نظرًا لأن الاستوديو توقع مستقبل CGI ، فقد بدأوا في البحث عن نظام يمكنه التعامل مع الترقية القوية التي رأوها في المستقبل.</p>
<p>اختارت ILM Python 1.4 بدلاً من Perl و Tcl ، واختارت استخدام Python لأنها كانت أسرع بكثير للاندماج في بنيتها التحتية الحالية. نظرًا لسهولة قابلية التشغيل البيني لـ Python مع C و C ++ ، كان من السهل على ILM استيراد Python إلى برنامج الإضاءة الخاص بهم. سمح لهم ذلك بوضع Python في أماكن أكثر ، واستخدامها لتغليف مكونات البرامج وتوسيع تطبيقات الرسوم القياسية الخاصة بهم.</p>
<p>استخدم الاستوديو Python في جوانب أخرى متعددة لعملهم. يستخدم المطورون Python لتتبع وظائف خطوط الأنابيب ومراجعتها ، والحفاظ على قاعدة بيانات لكل صورة يتم إنتاجها لكل فيلم. نظرًا لأنه تم التحكم في المزيد والمزيد من برامج ILM بواسطة Python ، فقد أنشأت مجموعة أدوات موحدة أبسط سمحت بخط أنابيب إنتاج أكثر فعالية. للحصول على مثال من العالم الحقيقي ، لا تنظر أبعد من OpenEXR ، تنسيق ملف HD يستخدمه ILM. كجزء من الحزمة ، تم تضمين PyIlmBase (على الرغم من أنه يحتوي على تبعية Boost).</p>
<p>على الرغم من المراجعات العديدة ، لا تزال ILM تجد أن Python هي الحل الأفضل لاحتياجاتها. يضمن الجمع بين كود مفتوح المصدر مع القدرة على تغييرات المنفذ الخلفي أن Python ستستمر في تلبية احتياجات ILM لفترة طويلة.<br />
جوجل</p>
<p>كانت Google داعمة لـ Python منذ البداية تقريبًا. في البداية ، اتخذ مؤسسو Google قرار &#8220;Python حيث نستطيع ، C ++ حيث يجب علينا.&#8221; هذا يعني أنه تم استخدام C ++ حيث كان التحكم في الذاكرة أمرًا ضروريًا وكان وقت الاستجابة المنخفض مطلوبًا. في الجوانب الأخرى ، مكنت Python من سهولة الصيانة والتسليم السريع نسبيًا.</p>
<p>حتى عندما تمت كتابة نصوص أخرى لـ Google بلغة Perl أو Bash ، غالبًا ما تم إعادة ترميزها في Python. كان السبب بسبب سهولة النشر ومدى سهولة صيانة Python. في الواقع ، وفقًا لستيفن ليفي &#8211; مؤلف كتاب &#8220;In the Plex&#8221; ، تمت كتابة أول عنكبوت للزحف على الويب من Google لأول مرة في Java 1.0 وكان صعبًا للغاية لدرجة أنهم أعادوا كتابته في Python.</p>
<p>تعد Python الآن إحدى اللغات الرسمية من جانب خادم Google &#8211; C ++ و Java و Go هي اللغات الثلاث الأخرى &#8211; المسموح بنشرها في الإنتاج. وفي حال لم تكن متأكدًا حقًا من مدى أهمية لغة Python بالنسبة إلى Google ، فإن BDFL الخاص ببايثون ، Guido van Rossum ، عمل في Google من 2005 إلى 2012.</p>
<p>وفوق كل ذلك ، قال بيتر نورفيج:<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">&#8220;لقد كانت Python جزءًا مهمًا من Google منذ البداية ، ولا تزال كذلك مع نمو النظام وتطوره. اليوم العشرات من مهندسي Google يستخدمون Python ، ونحن نبحث عن المزيد من الأشخاص ذوي المهارات في هذه اللغة &#8220;.</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">موقع التواصل الاجتماعي الفيسبوك</span></strong></span></p>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">يحرص مهندسو الإنتاج على Facebook بشكل استثنائي على Python ، مما يجعلها ثالث أكثر اللغات شهرة في عملاق الوسائط الاجتماعية (خلف C ++ ولهجة PHP الخاصة بهم ، Hack). في المتوسط ​​، هناك أكثر من 5000 التزام بالمرافق والخدمات على Facebook ، وإدارة البنية التحتية ، والتوزيع الثنائي ، وتصوير الأجهزة ، والأتمتة التشغيلية.<br />
</span></p>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تعني سهولة استخدام مكتبات Python أن مهندسي الإنتاج ليسوا مضطرين لكتابة أو الحفاظ على نفس القدر من التعليمات البرمجية ، مما يسمح لهم بالتركيز على نشر التحسينات. كما أنه يضمن أن البنية التحتية لـ Facebook قادرة على التوسع بكفاءة.</span></p>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">وفقًا لما نشره Facebook عام 2016 ، فإن Python مسؤولة حاليًا عن خدمات متعددة في إدارة البنية التحتية. يتضمن ذلك استخدام TORconfig للتعامل مع إعداد تبديل الشبكة والتصوير ، و FBOSS لمفاتيح CLI الخاصة بمفتاح Whitebox ، واستخدام Dapper لجدولة أعمال الصيانة وتنفيذها.</p>
<p>نشر Facebook العديد من مشاريع Python مفتوحة المصدر المكتوبة لـ Py3 بما في ذلك Facebook Ads API وإطار عمل Python Async IRCbot. يقوم Facebook حاليًا بعملية ترقية بنيته التحتية والمعالجات إلى 3.4 من 2 ، وتساعد AsyncIO مهندسيها في هذه العملية.<br />
</span></p>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">انستغرام</span></strong></p>
<p>في عام 2016 ، تفاخر فريق هندسة Instagram بأنهم يديرون أكبر عملية نشر في العالم لإطار عمل ويب Django ، والذي تمت كتابته بالكامل بلغة Python. من المحتمل أن يظل هذا صحيحًا اليوم. يقول Min Ni ، مهندس برمجيات في Instagram ، هذا عن استخدامهم الإنتاجي لـ Python:<br />
</span></p>
<blockquote>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">&#8220;اخترنا في البداية استخدام Python بسبب شهرتها في البساطة والتطبيق العملي ، والتي تتماشى جيدًا مع فلسفتنا&#8221; افعل الشيء البسيط أولاً &#8220;.</span></p>
</blockquote>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">منذ ذلك الحين ، استثمر الفريق الهندسي في Instagram الوقت والموارد في الحفاظ على إمكانية نشر Python على نطاق واسع (حوالي 800 مليون مستخدم نشط شهريًا) يعملون في:<br />
</span></p>
<blockquote>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">&#8220;من خلال العمل الذي وضعناه في بناء إطار عمل فعال لخدمة الويب في Instagram ، نحن على ثقة من أننا سنواصل توسيع نطاق البنية التحتية للخدمة لدينا باستخدام Python. لقد بدأنا أيضًا في الاستثمار أكثر في لغة Python نفسها ، وبدأنا في استكشاف نقل Python من الإصدار 2 إلى الإصدار 3. &#8220;</span></p>
</blockquote>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">في عام 2017 ، قام Instagram بترحيل معظم قاعدة رموز Python الخاصة بهم من Python 2.7 إلى Python 3. يمكنك مشاهدة خطاب PyCon 2017 الرئيسي الذي قدمته Lisa Guo و Hui Ding والاستماع إلى تجربتهما مع هذا الترحيل الضخم للكود:</p>
<p><strong><span style="font-size: 20pt">سبوتيفي</span></strong></p>
<p>يعد عملاق دفق الموسيقى هذا مؤيدًا كبيرًا لـ Python ، حيث يستخدم اللغة بشكل أساسي لتحليل البيانات والخدمات الخلفية. في النهاية الخلفية ، هناك عدد كبير من الخدمات التي تتواصل جميعها عبر 0MQ ، أو ZeroMQ ، وهي مكتبة شبكة مفتوحة المصدر وإطار عمل مكتوب بلغة Python و C ++ (من بين لغات أخرى).</p>
<p>السبب وراء كتابة الخدمات بلغة Python هو أن Spotify يحب مدى سرعة خط التطوير عند الكتابة والترميز في Python. تستخدم جميع التحديثات الأخيرة لبنية Spotify gevent ، والتي توفر حلقة حدث سريعة مع واجهة برمجة تطبيقات متزامنة عالية المستوى.</p>
<p>لتقديم اقتراحات وتوصيات للمستخدمين ، يعتمد Spotify على حجم كبير من التحليلات. لتفسير ذلك ، يستخدم Spotify Luigi ، وحدة Python التي تتزامن مع Hadoop. تعالج هذه الوحدة النمطية مفتوحة المصدر كيفية عمل المكتبات معًا ، وتدمج سجلات الأخطاء بسرعة للسماح باستكشاف الأخطاء وإصلاحها وإعادة النشر.</p>
<p>في المجموع ، يستخدم Spotify أكثر من 6000 عملية Python فردية تعمل معًا عبر عقد مجموعة Hadoop.<br />
</span></p>
<p style="text-align: justify"><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">كورا</span></strong></p>
<p>لقد فكرت منصة الأسئلة والأجوبة الضخمة هذه والموجودة من قبل الجمهور طويلاً وبشدة في اللغة التي يريدون استخدامها لتنفيذ فكرتهم. كان تشارلي شيفر ، أحد مؤسسي Quora ، قد حصر اختيارهم في Python و C # و Java و Scala. كانت أكبر مشكلاتهم في المضي قدمًا مع بايثون هي الافتقار إلى التحقق من الكتابة والبطء النسبي.</p>
<p>وفقًا لـ Adam D’Angelo ، قرروا عدم استخدام C # لأنها لغة مملوكة لشركة Microsoft ولم يرغبوا في أن يكونوا مدينين بأي تغييرات مستقبلية تم طرحها. بالإضافة إلى ذلك ، فإن أي كود مفتوح المصدر لديه دعم من الدرجة الثانية في أحسن الأحوال.</p>
<p>كانت الكتابة بلغة Java أكثر إيلامًا من لغة Python ولم يتم تشغيلها بشكل جيد مع برامج بخلاف Java كما فعلت Python. في ذلك الوقت ، كانت Java أيضًا في مهدها ، لذلك كانوا قلقين بشأن الدعم المستقبلي وما إذا كانت اللغة ستستمر في النمو.</p>
<p>بدلاً من ذلك ، أخذ مؤسسو Quora زمام المبادرة من Google ، واختاروا استخدام Python حيث أمكنهم ذلك نظرًا لسهولة كتابتها وقابليتها للقراءة ، وطبقوا C ++ للأقسام الهامة للأداء. لقد تمكنوا من التغلب على افتقار Python إلى فحص الكتابة عن طريق كتابة اختبارات الوحدة التي تحقق نفس الشيء.</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">كان أحد الاعتبارات الرئيسية الأخرى لاستخدام بايثون هو وجود العديد من الأطر الجيدة في ذلك الوقت بما في ذلك Django و Pylons. بالإضافة إلى ذلك ، نظرًا لأنهم كانوا يعلمون أن Quora كان سيشمل تفاعلات الخادم / العميل والتي لن تكون بالضرورة تحميلات كاملة للصفحات ، فإن وجود Python و JS يلعبان جيدًا معًا كان إضافة كبيرة.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">نيتفليكس</span></strong></p>
<p>تستخدم Netflix لغة Python بطريقة مشابهة جدًا لـ Spotify ، حيث تعتمد على اللغة لتشغيل تحليل بياناتها على جانب الخادم. لكن الأمر لا يتوقف عند هذا الحد. تسمح Netflix لمهندسي البرمجيات باختيار اللغة التي سيتم الترميز بها ، وقد لاحظت زيادة كبيرة في عدد تطبيقات Python.</p>
<p>عند الاستطلاع ، يستشهد مهندسو Netflix بالمكتبة القياسية ومجتمع التطوير النشط للغاية والتنوع الغني لمكتبات الجهات الخارجية المتاحة لحل أي مشكلة معينة تقريبًا. بالإضافة إلى ذلك ، نظرًا لسهولة تطوير Python ، فقد أصبحت ركيزة أساسية في العديد من خدمات Netflix الأخرى.</p>
<p>أحد الأماكن الأساسية التي تستخدم فيها بايثون هو بوابة التنبيه المركزية. يعالج تطبيق الويب RESTful التنبيهات من أي مكان ، ثم يوجهها إلى الأشخاص أو المجموعات التي قد تحتاج إلى رؤيتها. بالإضافة إلى ذلك ، يتمتع التطبيق بالقدرة على قمع التنبيهات المكررة التي تم التعامل معها بالفعل وفي بعض الحالات ، تنفيذ حلول آلية مثل إعادة تشغيل عملية أو إنهاء شيء بدأ يبدو مهتزًا. يعد هذا التطبيق مكسبًا كبيرًا لـ Netflix بالنظر إلى الحجم الهائل للتنبيهات. التعامل معها بذكاء يعني عدم إغراق المطورين والمهندسين بالمكالمات المتكررة.</p>
<p>هناك مجال آخر تستخدمه Python في Netflix وهو تطبيقات القرد المستخدمة لتتبع التغييرات الأمنية والمحفوظات. تُستخدم هذه القرود لتتبع وتنبيه أي تغييرات في السياسات المتعلقة بأمن EC2 في أي مجموعة ، وتتبع أي تغييرات في هذه البيئات. يتم استخدامها أيضًا لضمان تتبع العشرات من شهادات SSL المرفقة بنطاقات Netflix المتعددة. في التتبع ، شهدت Netflix انخفاضًا في حالات انتهاء الصلاحية غير المتوقعة من ربع إلى لا شيء منذ عام 2012.<br />
</span></p>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">بصندوق الإسقاط</span></strong></p>
<p>يستخدم نظام التخزين السحابي هذا لغة Python في عميل سطح المكتب الخاص به. إذا كان لديك أي شك على الإطلاق حول كيفية استثمار Dropbox في Python ، فضع في اعتبارك أنه في عام 2012 ، تمكنوا من إقناع Guido van Rossum ، مبتكر Python وديكتاتور الخير مدى الحياة ، بعيدًا عن Google وفي حظيرة Dropbox.</p>
<p>انضم روسوم إلى Dropbox بشرط أن يكون مهندسًا وليس قائدًا أو حتى مديرًا. في عامه الأول ، كان قادرًا على المساعدة في تحقيق القدرة على مشاركة مخازن البيانات مع مستخدمين آخرين داخل مجتمع Dropbox.</p>
<p>في حين أن عددًا كبيرًا من مكتبات Dropbox والمكونات الداخلية هي ملكية وليست مفتوحة المصدر ، فقد أصدرت الشركة واجهة برمجة تطبيقات فعالة للغاية مشفرة بلغة Python تتيح لك معرفة كيف يفكر مهندسوها. يمكنك أيضًا القراءة بين السطور عند قراءة المقابلات مع مهندسي Dropbox حول نسبة كبيرة من الكود الجانبي للخادم الخاص بهم هو Python.</p>
<p>من المثير للاهتمام أيضًا ملاحظة أنه بينما يتم ترميز برامج جانب العميل في Python ، فإنها تستخدم مكتبات متنوعة على كل من أجهزة Mac و Windows للسماح بتجربة موحدة. هذا لأن Python لا يتم تثبيته مسبقًا على نظام التشغيل Windows وبناءً على جهاز Mac الخاص بك ، سيختلف إصدار Python الخاص بك.</p>
<p><strong><span style="font-size: 20pt">رديت</span></strong></p>
<p>كان لهذا الموقع 542 مليون زائر كل شهر خلال عام 2017 ، مما يجعله رابع أكثر المواقع زيارة في الولايات المتحدة والسابع الأكثر زيارة في العالم. في عام 2015 ، كان هناك 73.15 مليون مشاركة و 82.54 مليار مشاهدة للصفحة. وخلف ذلك كله ، كانت بايثون تشكل العمود الفقري للبرنامج.</p>
<p>تم ترميز Reddit في الأصل في Lisp ، ولكن في ديسمبر 2005 ، بعد ستة أشهر من إطلاقه ، تم إعادة تشفير الموقع إلى Python. كان السبب الرئيسي للتغيير هو أن بايثون كان لديها نطاق أوسع من مكتبات الأكواد وكانت أكثر مرونة من الناحية التطورية. يعد إطار عمل الويب الذي كان يدير الموقع في الأصل ، web.py ، الآن مشروعًا مفتوح المصدر.</p>
<p>في مقابلة عام 2009 ، سُئل ستيف هوفمان وأليكسيس أوهانيان خلال Pycon عن سبب استمرار Reddit في استخدام Python كإطار عمل لها. وفقًا لهوفمان ، السبب الأول هو نفس سبب التغيير:<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">&#8220;هناك مكتبة لكل شيء. لقد تعلمنا الكثير من هذه التقنيات والكثير من هذه الهياكل مع تقدمنا. لذلك ، عندما لا أفهم تجمعات الاتصال ، يمكنني فقط العثور على مكتبة حتى أفهمها بشكل أفضل بنفسي وأكتب مجموعتنا الخاصة. لا تفهم أطر عمل الويب ، لذلك سنستخدم أطر عمل شخص آخر حتى نصنع أطر عمل خاصة بنا &#8230; تمتلك Python عكازًا رائعًا من هذا القبيل. &#8220;</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">السبب الثاني لبقاء Reddit مع Python هو خيط مشترك يتم تشغيله من خلال جميع الشركات التي تبنيها. وفقًا لهوفمان ، إنها سهولة قراءة الكود:</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">&#8220;عندما نوظف موظفين جدد &#8230; لا أعتقد أننا قد وظفنا موظفًا يعرف بايثون. أقول فقط ، &#8220;كل ما تكتبه يجب أن يكون بلغة بايثون.&#8221; فقط حتى أتمكن من قراءته. وهو رائع لأنني أستطيع أن أرى من جميع أنحاء الغرفة ، بالنظر إلى شاشتهم ، ما إذا كانت الشفرة جيدة أم سيئة. لأن كود Python الجيد له بنية واضحة جدًا.</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">وهذا يجعل حياتي أسهل بكثير. [&#8230;] إنه معبر للغاية ، ومقروء للغاية ، وقابل للكتابة للغاية. وهذا فقط يبقي الحياة سلسة &#8221;<br />
</span></p>
<blockquote><p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt">تحديث: ونعم ، هذا يجعل الآن 9 شركات عالمية المستوى تستخدم Python في الإنتاج. في البداية لم نحسب Instagram بشكل منفصل لأن الشركة مملوكة لشركة Facebook. ولكن نظرًا للنطاق المثير للإعجاب الذي يعمل به فريق Instagram ، فقد اعتقدنا أنه من المنطقي منحهم نقطة منفصلة.<br />
</span></p></blockquote>
<p><span class="tlid-translation translation" lang="ar" style="font-size: 14pt"><strong><span style="font-size: 20pt">اي شخص اخر؟</span></strong></p>
<p>في هذا المنشور ، ألقينا نظرة على ثماني شركات برمجيات عالمية وناجحة تستخدم Python في الإنتاج. لكنهم ليسوا الوحيدين. اعتبارًا من 2018 ، وصل اعتماد Python إلى ذروة جديدة ويستمر في الصعود.</p>
<p>هل افتقدنا أحد هذه القائمة؟ اترك تعليقًا أدناه وأخبرنا عن متجر Python المفضل لديك!</span></p>
<p>The post <a rel="nofollow" href="https://arabdars.com/8-%d8%b4%d8%b1%d9%83%d8%a7%d8%aa-%d8%a8%d8%b1%d9%85%d8%ac%d9%8a%d8%a7%d8%aa-%d9%85%d9%86-%d8%a7%d9%84%d8%b7%d8%b1%d8%a7%d8%b2-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85%d9%8a-%d8%aa%d8%b3%d8%aa%d8%ae%d8%af/">8 شركات برمجيات من الطراز العالمي تستخدم بايثون</a> appeared first on <a rel="nofollow" href="https://arabdars.com">فيلم تعلم البرمجيات للطالب العربي</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://arabdars.com/8-%d8%b4%d8%b1%d9%83%d8%a7%d8%aa-%d8%a8%d8%b1%d9%85%d8%ac%d9%8a%d8%a7%d8%aa-%d9%85%d9%86-%d8%a7%d9%84%d8%b7%d8%b1%d8%a7%d8%b2-%d8%a7%d9%84%d8%b9%d8%a7%d9%84%d9%85%d9%8a-%d8%aa%d8%b3%d8%aa%d8%ae%d8%af/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
