2.2. المتغيرات والأنواع الأساسية#

المتغير هو اسم تربطه بقيمة باستخدام عامل =. وبعد الإسناد، يمكن استخدام الاسم في أي مكان يمكن أن تُستخدم فيه القيمة:

width = 320
height = 240
pixels = width * height
print(pixels)               # prints 76800

يُقيَّم الطرف الأيمن من = أولًا، ثم تُربط النتيجة بالاسم الموجود على اليسار. وتؤدي قراءة اسم لم يُسنَد إليه قط إلى إطلاق NameError.

المتغير ما هو إلا تسمية. فهو يشير إلى قيمة -- والقيمة توجد في مكان آخر، ويمكن أن يكون للقيمة نفسها أي عدد من التسميات.

Three labels pointing at three boxed values; reassigning a label moves the arrow, not the value.

المتغيرات تسميات تشير إلى قيم. إعادة إسناد متغير تحرّك التسمية؛ ولا تغيّر القيمة التي كانت التسمية تشير إليها.#

2.2.1. قواعد التسمية#

  • تبدأ الأسماء بحرف أو شرطة سفلية، وقد تحتوي على حروف وأرقام وشرطات سفلية. frame_count و_internal صحيحان؛ أما 1st_frame فهو خطأ في بناء الجملة.

  • الأسماء حساسة لحالة الأحرف: Width وwidth متغيران مختلفان.

  • تجنّب إعادة استخدام الأسماء المدمجة مثل list أو str أو id() أو print() -- فحجبها لا يطلق خطأً، لكن المدمج الأصلي يصبح غير قابل للوصول لبقية البرنامج النصي.

  • العُرف المتّبع: snake_case للمتغيرات والدوال، وALL_CAPS للثوابت التي لا تنوي تغييرها، وCamelCase لأسماء الأصناف.

2.2.2. الأنواع الأساسية#

لكل قيمة في Python نوع يحدد العمليات التي تدعمها. والأنواع الأربعة التي ستكتبها أكثر من غيرها هي:

  • int -- الأعداد الصحيحة، الموجبة أو السالبة. تنمو الأعداد الصحيحة في MicroPython بقدر ما تسمح الذاكرة. تُكتب القيم الحرفية كأرقام عادية: 0 و42 و-7. كما أن القيم الست عشرية (0x1A) والثمانية (0o17) والثنائية (0b1010) صحيحة أيضًا ومفيدة للسجلات وأقنعة البتات.

  • float -- الأعداد ذات الفاصلة العشرية أو الأُس: 3.14 و1.0 و-0.5 و2e6 (= 2,000,000.0). كل الأعداد العائمة على الكاميرا بصيغة IEEE 754 بطول 32 بت -- دقيقة إلى نحو سبعة أرقام معنوية.

  • bool -- إحدى القيمتين الحرفيتين True أو False (انتبه إلى حالة الأحرف).

  • str -- النص، يُكتب كأحرف بين علامتي اقتباس مفردتين أو مزدوجتين: "hello" و'OpenMV'. كلا أسلوبي الاقتباس متكافئان؛ اختر الأسلوب الذي يتيح لك تجنّب تهريب أحرف الاقتباس التي تظهر داخل السلسلة النصية.

هناك أيضًا قيمة خامسة جديرة بالمعرفة على الفور:

  • None -- القيمة الوحيدة من النوع NoneType. تُستخدم بمعنى "لا قيمة" أو "لم تُحدَّد بعد". الدوال التي لا تُرجع شيئًا صراحةً تُرجع None ضمنيًا.

2.2.3. فحص الأنواع وتحويلها#

تُرجع الدالة المدمجة type() نوع أي قيمة:

>>> type(42)
<class 'int'>
>>> type(3.14)
<class 'float'>
>>> type("hello")
<class 'str'>

كل نوع يعمل أيضًا كدالة تحويل. مرّر إليها قيمة من نوع مختلف فتحصل على القيمة المكافئة بالنوع الجديد -- عندما يكون التحويل محدد المعالم:

>>> int("42")
42
>>> int(3.9)
3                           # truncates toward zero, not rounds
>>> float("1.5")
1.5
>>> str(255)
'255'
>>> bool(0), bool(1), bool("")
(False, True, False)

التحويلات غير محددة المعالم تطلق ValueError:

>>> int("hello")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: invalid syntax for integer with base 10

2.2.4. إعادة الإسناد والتنميط الديناميكي#

يمكن إعادة إسناد اسم إلى قيمة من أي نوع في أي وقت. ما يلي صحيح قانونيًا:

x = 42
x = "now I'm a string"
x = 3.14

لا يربط Python المتغير بنوع. الكود الذي يعتمد على كون x عددًا صحيحًا يتوقع ببساطة عددًا صحيحًا عند النقطة التي يستخدمه فيها؛ وإذا حصل على شيء آخر، فستحصل على TypeError أثناء التشغيل.

ملاحظة

إعادة إسناد x لا تغيّر القيمة التي كان الربط القديم يشير إليها. وإذا كان اسمان يتشاركان القيمة نفسها، فإن إعادة إسناد أحدهما لا تؤثر على الآخر:

a = [1, 2, 3]
b = a                       # both point at the same list
a = "different now"
print(b)                    # still [1, 2, 3]

أما تغيير قيمة مشتركة فهو أمر مختلف: فطريقة مثل list.append تغيّر القيمة التي يشير إليها الربط، فيرى كل اسم آخر يشير إلى القيمة نفسها هذا التغيير.