بايثون هي لغة برمجة قوية وسهلة التعلم وممتعة للعب بها. ولكن إلى جانب الأساسيات، هناك الكثير من الميزات والحيل المخفية التي يمكن أن تساعدك على كتابة أكواد بايثون أكثر كفاءة وفعالية.
في هذه المقالة، سنكشف عن بعض هذه الميزات المخفية ونوضح لك كيفية استخدامها لتحسين مهاراتك في برمجة بايثون.
استكشاف ميزات بايثون المخفية
تحتوي لغة بايثون على العديد من الميزات المخفية، بعضها أكثر خفاءً من غيرها. يمكن أن تكون هذه الميزات مفيدة بشكل لا يصدق ويمكن أن تساعدك في كتابة أكواد أكثر كفاءة وقابلية للقراءة. ومع ذلك، قد يكون من الصعب أيضًا اكتشافها إذا كنت لا تعرف أين تبحث.
في الأقسام القليلة القادمة سنلقي نظرة على بعض الميزات التي من المفيد معرفتها والتي لا يعرفها جيدًا مبرمجو بايثون.
_ (الشرطة السفلية) في بايثون
أحد الجواهر الخفية في بايثون هو الشرطة السفلية (_
). إنه حرف متعدد الاستخدامات ويمكن استخدامه بطرق مختلفة في كود بايثون.
أولاً، يمكن استخدامها كمتغير في بايثون. وغالبًا ما تستخدم كمتغير يمكن التخلص منه، أي متغير يتم إعلانه ولكن لا يتم استخدام قيمته فعليًا.
for _ in range(5):
print("Hello, World!")
في الكود أعلاه، نحن لا نستخدم المتغير _
في أي مكان، فهو موجود هناك فقط لأن المتغير مطلوب بواسطة بناء جملة حلقة for
.
ثانيًا، يتم استخدام _
لتجاهل القيم المحددة. إذا لم تكن بحاجة إلى القيم المحددة أو لم يتم استخدام القيم، فما عليك سوى تعيين القيم للشرطة السفلية.
# Ignore a value when unpacking
x, _, y = (1, 2, 3) # x = 1, y = 3
هنا نحتاج إلى متغيري x
وy
، لكن بناء الجملة في بايثون لا يسمح لنا بالإعلان عنهما بدون وجود شيء بينهما، لذا نستخدم الشرطة السفلية.
أخيرًا، في وحدة تحكم بايثون، تمثل _
قيمة التعبير التي تم تنفيذها آخر مرة.
>>> 10 + 20
30
>>> _
30
ملاحظة: استخدام
_
لتخزين القيمة الأخيرة خاص بمترجم بايثون التفاعلي ولن يعمل في البرامج النصية!
تصحيح أخطاء Regex عبر Parse Tree
يمكن أن تكون التعبيرات العادية معقدة ويصعب فهمها. لحسن الحظ، يوفر بايثون ميزة مخفية لتصحيح أخطائها عبر شجرة التحليل. توفر وحدة re
في بايثون علامة re.DEBUG
التي يمكن استخدامها لتصحيح أخطاء التعبيرات العادية.
خذ بعين الاعتبار الكود التالي:
import re
re.compile("(\d+)\.(\d+)", re.DEBUG)
سيؤدي هذا إلى:
SUBPATTERN 1 0 0
MAX_REPEAT 1 MAXREPEAT
IN
CATEGORY CATEGORY_DIGIT
LITERAL 46
SUBPATTERN 2 0 0
MAX_REPEAT 1 MAXREPEAT
IN
CATEGORY CATEGORY_DIGIT
0. INFO 4 0b0 3 MAXREPEAT (to 5)
5: MARK 0
7. REPEAT_ONE 9 1 MAXREPEAT (to 17)
11. IN 4 (to 16)
13. CATEGORY UNI_DIGIT
15. FAILURE
16: SUCCESS
17: MARK 1
19. LITERAL 0x2e ('.')
21. MARK 2
23. REPEAT_ONE 9 1 MAXREPEAT (to 33)
27. IN 4 (to 32)
29. CATEGORY UNI_DIGIT
31. FAILURE
32: SUCCESS
33: MARK 3
35. SUCCESS
re.compile('(\\d+)\\.(\\d+)', re.DEBUG)
هذه هي شجرة تحليل التعبير العادي. وهي توضح أن التعبير العادي يحتوي على نمطين فرعيين ((\d+)
و(\d+))
، مفصولين بنقطة حرفية (.
).
يمكن أن يكون هذا مفيدًا بشكل لا يصدق عند تصحيح أخطاء التعبيرات العادية المعقدة. فهو يوفر لك تمثيلًا واضحًا ومرئيًا للتعبير العادي، ويوضح بالضبط ما يفعله كل جزء من التعبير.
ملاحظة: لا يعمل علم
re.DEBUG
مع الدالتينre.match()
أوre.search()
. فهو يعمل فقط معre.compile()
.
النقاط الحذفية
إن النقاط الثلاث في بايثون هي ميزة فريدة لا توجد عادة في لغات البرمجة الأخرى. يتم تمثيلها بثلاث نقاط متتالية (…) وهي في الواقع ثابتة مدمجة في بايثون. قد تتساءل، ما الذي يمكن استخدامه لهذا الغرض؟ دعنا نستكشف بعض تطبيقاتها.
يمكن استخدام علامات الحذف في بايثون كعلامة مكانية للكود. يمكن أن يكون هذا مفيدًا جدًا عند رسم مخطط لهيكل البرنامج ولكنك لم تنفذ جميع الأجزاء بعد. على سبيل المثال:
def my_func():
...
# TODO: implement this function
هنا، تشير النقاط الثلاث إلى أن my_func
غير مكتملة ويجب تنفيذها.
تلعب علامات الحذف في بايثون أيضًا دورًا في تقسيم المصفوفات متعددة الأبعاد، وخاصةً في مكتبات علوم البيانات مثل NumPy. وإليك كيفية استخدامها:
import numpy as np
# Create a 3D array
arr = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
# Use ellipsis to access elements
print(arr[..., 2])
سيؤدي هذا إلى الإخراج:
[[ 3 6]
[ 9 12]]
في هذه الحالة، يتم استخدام النقاط الثلاث للوصول إلى العنصر الثالث لكل مصفوفة فرعية في مصفوفتنا ثلاثية الأبعاد.
دالة ()dir
تُعد دالة dir()
جوهرة مخفية في بايثون. إنها دالة مدمجة قوية تُرجع قائمة بالأسماء في النطاق المحلي الحالي أو قائمة بسمات كائن.
عند استخدامها بدون وسيطة، تقوم dir()
بإرجاع قائمة بالأسماء في النطاق المحلي الحالي. فيما يلي مثال:
x = 1
y = 2
print(dir())
سيؤدي هذا إلى طباعة شيء مثل:
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'x', 'y']
x
و y
هي المتغيرات التي قمنا بتعريفها، والباقي هي أسماء مدمجة في بايثون.
عند استخدامها مع كائن كحجة، تقوم dir()
بإرجاع قائمة بسمات الكائن. على سبيل المثال، إذا استخدمناها مع كائن سلسلة:
print(dir('Hello, pyarabic!'))
سيؤدي هذا إلى:
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
هذه هي كل التوابع التي يمكنك استخدامها مع كائن السلسلة. dir()
هي دالة مفيدة عندما تريد استكشاف كائنات بايثون وفهم قدراتها.
دوال Lambda
دوال Lambda، المعروفة أيضًا باسم الدوال المجهولة، هي ميزة من ميزات بايثون تتيح لك إنشاء دوال صغيرة غير مسماة لمرة واحدة يمكنك استخدامها بسرعة ثم التخلص منها. إنها مثالية عندما تحتاج إلى دالة لفترة قصيرة من الوقت ولا تريد أن تزعج نفسك بقواعد تعريف الدوال الكاملة.
إليك كيفية إنشاء دالة lambda:
multiply = lambda x, y: x * y
print(multiply(5, 4))
الناتج:
20
في المثال أعلاه، قمنا بإنشاء دالة lambda تقوم بضرب رقمين معًا. ثم نستدعي الدالة بالرقمين 5 و4، فتُرجع 20.
ملاحظة
: على الرغم من أن دوال lambda قوية ومريحة، إلا أنه يجب استخدامها باعتدال. فالإفراط في استخدام دوال lambda قد يؤدي إلى صعوبة قراءة الكود وتصحيح أخطائه.
تسلسل عوامل مقارنة
يتيح لك بايثون ربط عوامل المقارنة بطريقة بديهية وسهلة القراءة. يمكن أن يوفر لك هذا الكثير من الوقت عند كتابة مقارنات معقدة.
على سبيل المثال، لنفترض أنك تريد التحقق مما إذا كان الرقم بين 1 و10. فبدلاً من كتابة مقارنتين منفصلتين ودمجهما باستخدام عامل and
، يمكنك القيام بما يلي:
x = 5
print(1 < x < 10)
الناتج:
True
في هذا المثال، 1 < x < 10
يعادل 1 < x وx < 10
. يتحقق بايثون من المقارنتين ويعيد True
إذا كان كلاهما صحيحًا، تمامًا كما لو كنت قد استخدمت عامل and
.
ملاحظة: يمكنك ربط عدد لا حصر له من المقارنات بهذه الطريقة. على سبيل المثال،
1 < x < 10 < x * 10 < 100
هو كود بايثون صالح تمامًا.
دالة ()zip
تُعد دالة zip()
في بايثون جوهرة مخفية لا تحظى بالاهتمام الذي تستحقه. يمكن لهذه الدالة، التي كانت جزءًا من بايثون منذ الإصدار 1.5، أن تجعل الكود الخاص بك أكثر نظافة وكفاءة من خلال السماح لك بالتكرار عبر تسلسلات متعددة بالتوازي.
فيما يلي مثال بسيط لكيفية عمله:
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
print(f"{name} is {age} years old.")
و الناتج:
Alice is 25 years old.
Bob is 30 years old.
Charlie is 35 years old.
ملاحظة: تتوقف دالة
zip()
عند نهاية أقصر تسلسل إدخال. لذا، إذا لم تكن تسلسلاتك بنفس الطول، فلن يتم رفع أي استثناء – ولكن قد تفقد بعض البيانات من التسلسلات الأطول.
المزخرفات
تعتبر المزخرفات ميزة أخرى قوية في بايثون يمكنها تبسيط الكود بشكل كبير. في الأساس، المزخرف هو دالة تأخذ دالة أخرى وتوسع سلوك الدالة الأخيرة دون تعديلها صراحةً.
لنلق نظرة على مثال. لنفترض أن لديك دالة تقوم بإجراء عملية، ولكنك تريد تسجيل وقت بدء العملية وانتهائها. يمكنك إضافة عبارات تسجيل مباشرة إلى الدالة، ولكن هذا من شأنه أن يربك الكود. بدلاً من ذلك، يمكنك إنشاء مُزخرف للتعامل مع التسجيل:
def log_decorator(func):
def wrapper():
print("Starting operation...")
func()
print("Operation finished.")
return wrapper
@log_decorator
def perform_operation():
print("Performing operation...")
perform_operation()
عند تشغيل هذا الكود، سوف تشاهد الناتج التالي:
Starting operation...
Performing operation...
Operation finished.
سطر @log_decorator
عبارة عن مزخرف. فهو يخبر بايثون بتمرير الدالة perform_operation()
إلى الدالة log_decorator()
. ثم تقوم الدالة log_decorator()
بتغليف الدالة perform_operation()
بكود إضافي لتسجيل بداية ونهاية العملية.
مديرو السياق وعبارة “with”
في بايثون، تعد أدوات إدارة السياق جوهرة مخفية يمكن أن تكون مفيدة للغاية في إدارة الموارد. فهي تسمح لك بتخصيص الموارد وتحريرها بدقة عندما تريد ذلك. المثال الأكثر استخدامًا على أدوات إدارة السياق هو عبارة with
.
دعونا نلقي نظرة على مثال:
with open('hello.txt', 'w') as f:
f.write('Hello, World!')
في هذا المثال، يتم استخدام عبارة with
لفتح ملف وتعيينه للمتغير f
. يتم إبقاء الملف مفتوحًا طوال مدة كتلة with
، ويتم إغلاقه تلقائيًا في النهاية، حتى إذا حدثت استثناءات داخل الكتلة. يضمن هذا إتمام عملية التنظيف نيابةً عنا.
ملاحظة: إن استخدام عبارة
with
يشبه القول، “مع هذا الشيء، افعل هذا الشيء، وبغض النظر عن كيفية نهايته، أغلقه بشكل صحيح”.
المولدات وعبارة Yield
المولدات هي نوع من العناصر القابلة للتكرار، مثل القوائم أو الثنائيات. لا تسمح هذه المولدات بالفهرسة ولكن لا يزال من الممكن تكرارها باستخدام حلقات for
. يتم إنشاؤها باستخدام الدوال وعبارة yield
.
يتم استخدام عبارة yield
لتعريف مولد، واستبدال إرجاع الدالة لتوفير نتيجة للمتصل بها دون تدمير المتغيرات المحلية.
إليك مولدًا بسيطًا يقوم بإنشاء أرقام زوجية:
def even_numbers(n):
for i in range(n):
if i % 2 == 0:
yield i
for number in even_numbers(10):
print(number)
الناتج:
0
2
4
6
8
على عكس الدوال العادية، لا يتم تدمير المتغيرات المحلية عند إنتاج الدالة. علاوة على ذلك، لا يمكن تكرار كائن المولد إلا مرة واحدة.
يمكن لهذه الميزات المخفية في بايثون، مثل مديري السياقات والمولدات، أن تجعل الكود أكثر كفاءة وقابلية للقراءة. وهي تستحق الفهم والاستخدام في برمجة بايثون.
بايثون هي لغة متعددة الاستخدامات تحتوي على مجموعة كبيرة من الميزات المخفية التي يمكن أن تجعل تجربة البرمجة أكثر كفاءة ومتعة. من علامة underscore التي غالبًا ما يتم تجاهلها، إلى مفهوم metaclasses القوي والمعقد، هناك دائمًا شيء جديد لاكتشافه في بايثون. مفتاح إتقان هذه الميزات هو فهم متى وكيف تستخدمها بشكل مناسب في الكود.
اكتشاف المزيد من بايثون العربي
اشترك للحصول على أحدث التدوينات المرسلة إلى بريدك الإلكتروني.