في هذا البرنامج التعليمي، سوف نتعرف على الأنواع الثابتة وكيف تساعد في تحسين إمكانية قراءة التعليمات البرمجية. إذا لم تكن مألوفًا، فإن الثوابت هي الأسماء التي تمثل القيم التي لا تتغير أثناء تنفيذ البرنامج. هم المفهوم الأساسي الأكثر شيوعا في البرمجة. ومع ذلك، ليس لدى بايثون صيغة مخصصة لتعريف الثوابت. بشكل عام، ثوابت بايثون متغيرة ولا تتغير أبدًا. سنجري مناقشة تفصيلية حول ثابت بايثون في القسم التالي.
ما هي الثوابت؟
بشكل عام، يتم استخدام مصطلح ثابت في الرياضيات، وهو قيمة أو كمية لا تتغير أبدًا. في البرمجة، يشير الثابت إلى الاسم المرتبط بقيمة لا تتغير أبدًا أثناء تنفيذ البرمجة. يختلف ثابت البرمجة عن الثوابت الأخرى، ويتكون من شيئين - اسم وقيمة مرتبطة به. سيصف الاسم معنى الثابت، والقيمة هي التعبير الملموس عن الثابت نفسه.
بمجرد تحديد الثابت، يمكننا فقط الوصول إلى قيمته ولكن لا يمكننا تغييره بمرور الوقت. ومع ذلك، يمكننا تعديل قيمة المتغير. ومن الأمثلة الواقعية - سرعة الضوء، وعدد الدقائق في الساعة، واسم المجلد الجذر للمشروع.
ما هو أمر التصدير في لينكس
لماذا استخدام ثابت؟
في لغات البرمجة، تسمح لنا الثوابت بالحماية من تغيير قيمتها عن طريق الخطأ والذي يمكن أن يسبب أخطاء يصعب تصحيحها. من المفيد أيضًا جعل التعليمات البرمجية أكثر قابلية للقراءة والصيانة. دعونا نرى بعض مزايا الثابت.
الثوابت المعرفة من قبل المستخدم
نحن بحاجة إلى استخدام اصطلاح التسمية في بايثون لتحديد الثابت في بايثون. يجب أن نكتب الاسم بأحرف كبيرة مع وجود شرطة سفلية تفصل بين الكلمات.
فيما يلي أمثلة لثوابت بايثون المعرفة من قبل المستخدم -
PI = 3.14 MAX_SPEED = 300 DEFAULT_COLOR = ' 33[1;34m' WIDTH = 20 API_TOKEN = '567496396372' BASE_URL = 'https://api.example.com' DEFAULT_TIMEOUT = 5 BUILTINS_METHODS = ('sum', 'max', 'min', 'abs') INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', ... ]
لقد استخدمنا نفس الطريقة التي أنشأنا بها المتغيرات في بايثون. لذلك يمكننا أن نفترض أن ثوابت بايثون هي مجرد متغيرات، والفرق الوحيد هو أن الثابت يستخدم الأحرف الكبيرة فقط.
إن استخدام الأحرف الكبيرة يجعل الثابت بارزًا بين المتغيرات، وهو ممارسة مفيدة أو مفضلة.
ناقشنا أعلاه المستخدمين المحددين من قبل المستخدم؛ توفر بايثون أيضًا العديد من الأسماء الداخلية التي يمكن اعتبارها ويجب التعامل معها كثوابت.
ثوابت مهمة في بايثون
في هذا القسم، سوف نتعرف على بعض الثوابت الداخلية التي تستخدم لجعل كود بايثون أكثر قابلية للقراءة. دعونا نفهم بعض الثوابت الهامة.
الثوابت المضمنة
في الوثائق الرسمية، حقيقي و خطأ شنيع يتم سردها باعتبارها الثابت الأول. هذه هي قيم Python Boolean وهي مثيل int. أ حقيقي له قيمة 1، و خطأ شنيع لديه قيمة 0.
مثال -
>>> True True >>> False False >>> isinstance(True, int) True >>> isinstance(False, int) True >>> int(True) 1 >>> int(False) 0 >>> True = 42 ... SyntaxError: cannot assign to True >>> True is True True >>> False is False True
تذكر أن الأسماء الحقيقية والخطأ هي ثوابت صارمة. بمعنى آخر، لا يمكننا إعادة تعيينها، وإذا حاولنا إعادة تعيينها، فسنحصل على خطأ في بناء الجملة. هاتان القيمتان عبارة عن كائنات مفردة في بايثون، مما يعني وجود مثيل واحد فقط.
أسماء دندر الداخلية
لدى بايثون أيضًا العديد من العناصر الداخلية رعد الأسماء التي يمكن أن نعتبرها ثوابت. هناك العديد من هذه الأسماء الفريدة، سنتعرف على __name__ و__file__ في هذا القسم.
ترتبط السمة __name__ بكيفية تشغيل جزء معين من التعليمات البرمجية. عند استيراد وحدة نمطية، تقوم لغة Python الداخلية بتعيين __name__ إلى سلسلة تحتوي على اسم الوحدة.
new_file.py
print(f'The type of __name__ is: {type(__name__)}') print(f'The value of __name__ is: {__name__}')
في سطر الأوامر واكتب الأمر التالي -
python -c 'import new_file'
يتم استخدام -c لتنفيذ جزء صغير من كود Python في سطر الأوامر. في المثال أعلاه، قمنا باستيراد ملف ملف جديد الوحدة التي تعرض بعض الرسائل على الشاشة.
انتاج -
The type of __name__ is: The value of __name__ is: timezone
كما نرى أن __name__ يخزن السلسلة __main__، مما يشير إلى أنه يمكننا تشغيل الملفات القابلة للتنفيذ مباشرة كبرنامج بايثون.
من ناحية أخرى، تحتوي السمة __file__ على الملف الذي تقوم Python باستيراده أو تنفيذه حاليًا. إذا استخدمنا السمة __file__ داخل الملف، فسنحصل على المسار إلى الوحدة نفسها.
دعونا نرى المثال التالي -
مثال -
ما هو ييميل
print(f'The type of __file__ is: {type(__file__)}') print(f'The value of __file__ is: {__file__}')
انتاج:
The type of __file__ is: The value of __file__ is: D:Python Project ew_file.py
يمكننا أيضًا الركض مباشرةً وسنحصل على نفس النتيجة.
مثال -
print(f'The type of __file__ is: {type(__file__)}') print(f'The value of __file__ is: {__file__}')
انتاج:
python new_file.py The type of __file__ is: The value of __file__ is: timezone.py
سلسلة مفيدة والثوابت الرياضية
هناك العديد من الثوابت القيمة في المكتبة القياسية. يرتبط بعضها بشكل صارم بوحدات ووظائف وفئات محددة؛ العديد منها عامة، ويمكننا استخدامها في عدة سيناريوهات. في المثال أدناه، سوف نستخدم الرياضيات والوحدات المتعلقة بالسلاسل، الرياضيات والسلسلة، على التوالي.
دعونا نفهم المثال التالي -
مثال -
>>> import math >>> math.pi 3.141592653589793 >>> math.tau 6.283185307179586 >>> math.nan nan >>> math.inf inf >>> math.sin(30) -0.9880316240928618 >>> math.cos(60) -0.9524129804151563 >>> math.pi 3.141592653589793
ستلعب هذه الثوابت دورًا حيويًا عندما نكتب تعليمات برمجية متعلقة بالرياضيات أو نقوم ببعض العمليات الحسابية المحددة.
دعونا نفهم المثال التالي -
مثال -
import math class Sphere: def __init__(self, radius): self.radius = radius def area(self): return math.pi * self.radius**2 def perimeter(self): return 2 * math.pi * self.radius def projected_volume(self): return 4/3 * math.pi * self.radius**3 def __repr__(self): return f'{self.__class__.__name__}(radius={self.radius})'
في الكود أعلاه استخدمنا math.pi بدلا من العرف باي الثوابت. يوفر الثابت المرتبط بالرياضيات المزيد من السياقات للبرنامج. تتمثل ميزة استخدام ثابت math.pi في أننا إذا كنا نستخدم إصدارًا أقدم من Python، فسنحصل على إصدار 32 بت من Pi. إذا استخدمنا البرنامج أعلاه في الإصدار الحديث من Python، فسنحصل على إصدار 64 بت من pi. لذا فإن برنامجنا سوف يتكيف ذاتيًا مع بيئة التنفيذ الملموسة الخاصة به.
توفر وحدة السلسلة أيضًا بعض ثوابت السلسلة المضمنة المفيدة. يوجد أدناه جدول اسم وقيمة كل ثابت.
اسم | قيمة |
---|---|
ascii_lowercase | Abcdefghijklmnopqrstuvwxyz |
ascii_uppercase | ABCDEFGHIJKLMNOPQRSTUVWXYZ |
ascii_letters | ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz |
أرقام | 0123456789 |
com.hexdigits | 0123456789abcdefABCDEF |
octdigits | 01234567 |
يمكننا استخدام هذه الثوابت المرتبطة بالسلاسل في التعبيرات العادية، ومعالجة اللغة الطبيعية، مع الكثير من معالجة السلاسل، والمزيد.
ثوابت نوع التعليق التوضيحي
منذ إصدار Python 3.8، تتضمن وحدة الكتابة فئة نهائية تسمح لنا بكتابة الثوابت. إذا استخدمنا الفئة النهائية لتحديد الثوابت في البرنامج، فسنحصل على خطأ النوع الثابت الذي يتحقق منه مدقق mypy وسيُظهر أنه لا يمكننا إعادة التعيين إلى الاسم النهائي. دعونا نفهم المثال التالي.
مثال -
from typing import Final MAX_Marks: Final[int] = 300 MAX_Students: Final[int] = 500 MAX_Marks = 450 # Cannot assign to final name 'MAX_SPEED' mypy(error)
لقد حددنا المتغير الثابت مع الفئة النهائية التي أشارت إلى خطأ النوع للإبلاغ عن خطأ في حالة إعادة تعيين اسم معلن. ومع ذلك، فإنه يحصل على تقرير عن خطأ مدقق النوع؛ تقوم Python بتغيير قيمة MAX_SPEED. لذلك، لا يمنع Final إعادة التعيين العرضي المستمر في وقت التشغيل.
ثوابت السلسلة
كما ناقشنا في القسم السابق، لا تدعم بايثون الثوابت الصارمة؛ إنه يحتوي فقط على متغيرات لا تتغير أبدًا. لذلك، يتبع مجتمع بايثون اصطلاح التسمية المتمثل في استخدام الأحرف الكبيرة لتحديد المتغيرات الثابتة.
يمكن أن تكون مشكلة إذا كنا نعمل في مشروع بايثون كبير مع العديد من المبرمجين على مستويات مختلفة. لذلك سيكون من الممارسات الجيدة أن يكون لدينا آلية تسمح لنا باستخدام ثوابت صارمة. كما نعلم، بايثون هي لغة ديناميكية، وهناك عدة طرق لجعل الثوابت غير قابلة للتغيير. وفي هذا القسم سنتعرف على بعض هذه الطرق.
سمات .__slot__
توفر فئات Python إمكانية استخدام سمات __slots__. تحتوي الفتحة على آلية خاصة لتقليل حجم الكائنات. إنه مفهوم تحسين الذاكرة على الأشياء. إذا استخدمنا سمة __slots__ في الفصل الدراسي، فلن نتمكن من إضافة المثيل الجديد، لأنه لا يستخدم سمات __dict__. بالإضافة إلى ذلك، عدم وجود .__قاموس__ تتضمن السمة تحسينًا من حيث استهلاك الذاكرة. دعونا نفهم المثال التالي.
مثال - بدون استخدام سمات __slots__
class NewClass(object): def __init__(self, *args, **kwargs): self.a = 1 self.b = 2 if __name__ == '__main__': instance = NewClass() print(instance.__dict__)
انتاج -
سلسلة إلحاق جافا
{'a': 1, 'b': 2}
يحتوي كل كائن في بايثون على قاموس ديناميكي يسمح بإضافة السمات. تستهلك القواميس قدرًا كبيرًا من الذاكرة، كما أن استخدام __الفتحات__ يقلل من إهدار المساحة والذاكرة. دعونا نرى مثالا آخر.
مثال -
class ConstantsName: __slots__ = () PI = 3.141592653589793 EULER_NUMBER = 2.718281828459045 constant = ConstantsName() print(constant.PI) print(constant.EULER_NUMBER) constant.PI = 3.14 print(constant.PI)
انتاج -
3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 10, in AttributeError: 'ConstantsName' object attribute 'PI' is read-only
في الكود أعلاه، قمنا بتهيئة سمات الفئة باستخدام سمات الفتحات. المتغير له قيمة ثابتة، إذا حاولنا إعادة تعيين المتغير، فسوف نحصل على خطأ.
@مصمم الديكور العقاري
يمكننا أيضا أن نستخدم @ملكية Decorator لإنشاء فئة تعمل كمساحة اسم للثوابت. نحتاج فقط إلى تحديد خاصية الثوابت دون تزويدها بطريقة ضبط. دعونا نفهم المثال التالي.
مثال -
class ConstantsName: @property def PI(self): return 3.141592653589793 @property def EULER_NUMBER(self): return 2.718281828459045 constant = ConstantsName() print(constant.PI) print(constant.EULER_NUMBER) constant.PI = 3.14 print(constant.PI)
انتاج -
3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 13, in AttributeError: can't set attribute
إنها مجرد خصائص للقراءة فقط، وإذا حاولنا إعادة تعيينها، فسنحصل على خطأ في السمة.
إذا كان ملخص روديارد كيبلينج
وظيفة المصنع المسمى ()
تأتي وحدة التجميع في Python مع وظيفة المصنع المسماة nametuple(). باستخدام اسمهtuple() دالة، يمكننا استخدام الحقول المسماة وترميز النقطة للوصول إلى عناصرها. نحن نعلم أن الصف غير قابل للتغيير، مما يعني أنه لا يمكننا تعديل كائن صف موجود مسمى في مكانه.
دعونا نفهم المثال التالي.
مثال -
from collections import namedtuple ConstantsName = namedtuple( 'ConstantsName', ['PI', 'EULER_NUMBER'] ) constant = ConstantsName(3.141592653589793, 2.718281828459045) print(constant.PI) print(constant.EULER_NUMBER) constant.PI = 3.14 print(constant.PI)
انتاج -
3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 17, in AttributeError: can't set attribute
مصمم @dataclass
كما يوحي اسمها، تحتوي فئة البيانات على بيانات، ويمكن أن تتكون من طرق، ولكنها ليست هدفها الأساسي. نحتاج إلى استخدام مصمم البيانات @dataclass لإنشاء فئات البيانات. يمكننا أيضًا إنشاء الثوابت الصارمة. يأخذ مصمم @dataclass وسيطة مجمدة تسمح لنا بوضع علامة على فئة البيانات الخاصة بنا على أنها غير قابلة للتغيير. من مزايا استخدام @dataclass Decorator أنه لا يمكننا تعديل سمة المثيل الخاصة به.
دعونا نفهم المثال التالي.
مثال -
from dataclasses import dataclass @dataclass(frozen=True) class ConstantsName: PI = 3.141592653589793 EULER_NUMBER = 2.718281828459045 constant = ConstantsName() print(constant.PI) print(constant.EULER_NUMBER) constant.PI = 3.14 print(constant.PI)
انتاج -
3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 19, in File '', line 4, in __setattr__ dataclasses.FrozenInstanceError: cannot assign to field 'PI'
توضيح -
في الكود أعلاه، قمنا باستيراد مُزخرف @dataclass. استخدمنا هذا الديكور لـ ConstantsName لجعله فئة بيانات. لقد قمنا بتعيين الوسيطة المجمدة على True لجعل فئة البيانات غير قابلة للتغيير. لقد أنشأنا مثيل فئة البيانات، ويمكننا الوصول إلى جميع الثوابت ولكن لا يمكننا تعديلها.
الطريقة الخاصة .__setattr__()
تسمح لنا لغة بايثون باستخدام طريقة خاصة تسمى .__setattr__(). باستخدام هذه الطريقة، يمكننا تخصيص عملية تعيين السمة لأن Python تستدعي الطريقة تلقائيًا في كل تعيين سمة. دعونا نفهم المثال التالي -
مثال -
class ConstantsName: PI = 3.141592653589793 EULER_NUMBER = 2.718281828459045 def __setattr__(self, name, value): raise AttributeError(f'can't reassign constant '{name}'') constant = ConstantsName() print(constant.PI) print(constant.EULER_NUMBER) constant.PI = 3.14 print(constant.PI)
انتاج -
3.141592653589793 2.718281828459045 Traceback (most recent call last): File '', line 22, in File '', line 17, in __setattr__ AttributeError: can't reassign constant 'PI'
لا يسمح الأسلوب __setattr__() بإجراء أي عملية إسناد على سمات الفصل. إذا حاولنا إعادة التعيين، فسيؤدي ذلك إلى رفع ملف خطأ في السمة.
خاتمة
الثوابت هي الأكثر استخداما في المفهوم في البرمجة وخاصة في المصطلح الرياضي. تعرفنا في هذا البرنامج التعليمي على المفاهيم المهمة للثوابت ونكهاتها. يستخدم مجتمع بايثون الأحرف الكبيرة كاتفاقية اسم لتحديد الثوابت. ومع ذلك، فقد ناقشنا بعض الطرق المتقدمة لاستخدام الثوابت في بايثون. لقد ناقشنا كيفية تحسين إمكانية قراءة التعليمات البرمجية وإمكانية إعادة استخدامها وقابلية صيانتها باستخدام الثوابت. لقد ذكرنا كيفية تطبيق تقنيات مختلفة لجعل ثوابت بايثون ثابتة تمامًا.