در مقالهی قبلی با تعدادی از ترفندهای کمتر شناخته شدهی پایتون آشنا شدیم. در این مقاله با تعداد دیگری از آنها آشنا خواهیم شد.
1- نمایش نتایج قابل خواندن
دستور Print عادی در بیشتر مواقع عملکرد خوبی دارد، اما زمانی که خروجی به شکل جداول، JSON یا شامل چند نتیجه باشد، باید تغییراتی در دستور فوق اعمال شود یا در صورت لزوم از بستههای خارجی استفاده کرد.
''' pprint (pretty print)'''
from pprint import pprint
import json
f = open('data.json',)
data = json.load(f)
pprint(data)
f.close()
خروجی قطعه کد بالا به شرح زیر است:
{'glossary':
{'GlossDiv':
{'GlossDef':
{'GlossSeeAlso': ['GML', 'XML'],'para': 'A meta-markup language, used '
'to create markup languages ''such as DocBook.'},
'GlossSee': 'markup'},
'title': 'example glossary'}}
''' Normal Print '''
اکنون، به مثال دیگری در این زمینه دقت کنید که نحوهی نمایش عادی را نشان میدهد:
import json
f = open('data.json',)
data = json.load(f)
print(data)
f.close()
خروجی قطعه کد بالا به شرح زیر است:
{'glossary': {'title': 'example glossary', 'GlossDiv': {'GlossDef': {'para': 'A meta-markup language, used to create markup languages such as DocBook.', 'GlossSeeAlso': ['GML', 'XML']}, 'GlossSee': 'markup'}}}
2- دریافت باقیمانده و ضرب به شکل یک تاپل
divmod نوعی تابع داخلی در پایتون است که دو عدد را به عنوان ورودی میگیرد و باقیمانده و ضریب را در قالب نوع دادهای تاپل (Tuple) برمیگرداند.
a = 2560
b = 27result = divmod(a,b)
print(result)
--------------------
(94, 22)
3- حل معادلههای ریاضی در یک خط
پایتون یک تابع بسیار مفید به نام ()eval برای حل عبارتها در اختیار توسعهدهندگان قرار میدهد. تابع فوق سه پارامتر به عنوان ورودی دریافت میکند. این سه پارامتر به ترتیب عبارت ریاضی که باید ارزیابی شود، ارجاع به یک متغیر و مرجع مقدار مستقیم هستند.
4- متد Else
میتوانید از کلمه کلیدی else در حلقه for استفاده کنید. در این حالت باید بلوک کدی را مشخص کنید که پس از اجرای موفقیتآمیز حلقه for اجرا شود. این بلوک میتواند برای تعیین هر شرط یا پیامی برای حلقه استفاده شود.
for x in range(9):
print(x)
else:
print("Finally finished!")
5- تبدیل یک تغییرپذیر به تغییرناپذیر
Type Casting یکی از ویژگیهای کاربردی پایتون است که به شما امکان میدهد یک ساختار داده را به دیگری تبدیل کنید. با کمک ویژگی فوق، میتوانید یک ساختار تغییر پذیر را به یک ساختار داده تغییرناپذیر تبدیل کنید.
''' Mutable List '''
lst = [1,2,3,4,5]
lst[0] = 6
print(lst)
------------
[6,2,3,4,5]''' Converting It to Immutable '''
lst = [1,2,3,4,5]
lst2 = tuple(lst)
lst[0] = 6
--------------
TypeError: 'tuple' object does not support item assignment
6- ساخت توالی به عنوان نیازمندی
Generator در پایتون نوعی تابع خاص است که یک شی را برمیگرداند که قابل شمارش است. به عبارت ساده Generator اجازه میدهد در صورت نیاز یک دنباله (sequence) تولید کند. بزرگترین مزیتی که ژنراتورها دارند در استفاده بهینهاز حافظه است. همچنین، اجازهی شمارش و انجام محاسبههای خاصی که lazy evaluations نام دارند را میدهند.
def fibo(limit):
a,b = 0,1
while a<limit:
yield a
a, b = b, a+b
series = fibo(10)print(next(series)) ## 0
print(next(series)) ## 1
print(next(series)) ## 1
7- گزارشیگیری به جای چاپ اطلاعات در هنگام اشکالزدایی
گزارشگیری، فرآیند ضبط جریان کدها هنگام اجرای برنامههای کاربردی است که نقش مهمی در اشکالزدایی کدها دارند. با اینحال، پایتون اجازه میدهد به جای چاپ این اطلاعات روی صفحهنمایش، اطلاعات کاربردی را حتی پس از بسته شدن برنامه در یک فایل ذخیره کنید و در فرصت مناسب بررسی کنید. گزارشهای ساخته شده در قالب رکوردها، شمارهی خط و نام ماژول هستند. لازم به توضیح است که دستور Print تنها در مدت زمانی که یک برنامه در حال اجرا است، وضعیت مربوط به دادهها و عملکرد برنامه را نشان میدهد. پایتون ماژولی به نام logging برای تولید و ذخیرهسازی گزارشها دارد.
''' Logging Code For Zero Division Error '''
import logging
a = 10
b = 0
try:
c = a / b
except Exception as e:
logging.error("Exception Occurred", exc_info=True) ## At default it is True
8- ذخیرهسازی اطلاعات در قالب گزارش
ERROR:root:Exception Occurred ## If exc_info=False then only this message will print
Traceback (most recent call last):
File "C:\Users\Name\Desktop\logging_code.py", line 5, in <module>
c = a / b
ZeroDivisionError: division by zero
خروجی قطعه کد بالا در قالب نمایش اطلاعات روی صفحهنمایش:
Traceback (most recent call last):
File "main.py", line 3, in <module>
print(a/b)
ZeroDivisionError: division by zero
9- افزودن هوشمندانهی عملکردهای جدید
دکوراتور (Decorator) یکی از ویژگیهای جذاب پایتون است که اجازه میدهد، بدون تغییر صریح کدهای موجود، عملکرد جدیدی به آنها اضافه کنید. یکی از کاربردهای عالی دکوراتور اضافه کردن قابلیت معدلگیری به تابعی است که قرار است عملیات جمع و درصد را بدون نیاز به ویرایش تابع محاسبه کند.
import functools
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
numbers = list(args)
print("Percentage: ",((sum(numbers)*100)/len(numbers)))
result = func(*args,**kwargs)
print("Total: ",sum(numbers) )
return result
return wrapper
@decorator
def average(*numbers):
return sum(list(numbers))/len(list(numbers))
result = average(77,89,93,96)
print("Average: ", result)
خروجی قطعه کد بالا به شرح زیر است:
Percentage: 8875.0
Total: 355
Average: 88.75
10- استفاده از Context Managers برای مدیریت منابع
Context Manager یک ابزار عالی در پایتون است که به شما امکان میدهد منابع را هر زمان که نیاز داشتید اختصاص داده یا آزاد کنید. یکی از مزایای بزرگ Context Managers این است که اطمینان حاصل خواهید کرد فایلها پس از استفاده، بسته میشوند.
with open ('content.txt','w') as f:
f.write("Hello Python")
11- PyForest (برای برنامهنویسان باهوش، اما تنبل!)
این ترفند به معنای واقعی کلمه یکی از جذابترین ترفندهایی است که برنامهنویسان در بیشتر پروژهها از آن استفاده میکنند. برخی مواقع، شرایط ایجاب میکند زمان زیادی را صرف Import کردن کتابخانههای اصلی مانند Numpy، Pandas و غیره کنید. برای صرفهجویی در زمان کتابخانه pyforest در اختیار شما قرار دارد که تمام کتابخانههای لازم که برای یک پروژهی یادگیری ماشین مورد نیاز است را به صورت خودکار وارد میکند.
from pyforest import *
12- Itettools
این ماژول میتواند طیف گستردهای از بلوکهای سازنده را با الهام از ساختارهای APL، Haskell و SML پیادهسازی میکند. همچنین، توابع کاربردی جذاب زیادی را ارائه میکند که باعث شده این کتابخانه به گوهری گرانبها در پایتون تبدیل شود. برای آگاهی در ارتباط با عملکردهای مختلف موجود در این کتابخانه، اسناد مربوطه را بررسی کنید.
13- مجموعهها در پایتون
مجموعه (Collection) در پایتون، کانتینرهایی (containers) هستند که برای ذخیرهی مجموعهی دادهها استفاده میشوند. پایتون مجموعهای از بستهها را ارائه میکند که شامل انواع مختلفی از کانتینرهای مفید است که میتوانند برای اهداف مختلف استفاده شوند. برخی از این کانتینرها عبارتند از:
- Counter: یک مقدار تکرارپذیر (iterable) را میگیرد و یک دیکشنری را برمیگرداند که در آن Keys برابر با عناصر و Value برابر با تعداد تکرارها هستند.
- Namedtuple: یک تاپل با نام را برمیگرداند. نکتهای که باید در ارتباط با اشیا namedtuple به آن دقت کنید این است که درست مانند تاپلهای معمولی تغییرناپذیر هستند. این حرف بدان معنا است که شما نمیتوانید پس از ساخت نمونه namedtuple، فیلدهای جدید افزوده یا فیلدهای موجود را تغییر دهید.
- Ordered Dict: اگر تجربهی کدنویسی با پایتون را داشته باشید، به خوبی از این نکته اطلاع دارید که همراه با انتشار پایتون 3.6 تغییراتی به وجود آمد. به طوری که کلاس داخلی dict آیتمها را به ترتیب نگهداری میکند. به بیان دیگر، Ordered Dict ترتیب عناصر را به ترتیب ورود کلید آنها نگهداری، میکند.
- Default Dict: شامل مقادیر پیش فرض برای هر کلید است، البته به شرطی که اختصاص داده نشده باشند.
14- اشکالزدایی اسکریپتها
این امکان وجود دارد تا نقاط شکستی در اسکریپتهای پایتون از طریق بهکارگیری ماژول <pdb> ایجاد کنیم. قطعه کد زیر نحوهی انجام اینکار را نشان میدهد:
import pdb
pdb.set_trace()
15- ارزیابی وضعیت یک شی
برخی زمانها نیاز داریم اطلاعات دقیقی در ارتباط با اشیا در پایتون به دست آوریم. برای این منظور، باید متد dir را فراخوانی کنیم. قطعه کد زیر نحوهی انجام اینکار را نشان میدهد.
Numbers= [1, 3, 5, 7]
print( dir(Numbers) )
خروجی قطعه کد بالا به شرح زیر است:
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
16- ساخت یک دیکشنری از دو مجموعهی مرتبط با هم
برخی مواقع دو مجموعه مرتبط با یکدیگر داریم و نیاز داریم بر مبنای آنها یک دیکشنری ایجاد کنیم. قطعه کد زیر نحوهی انجام این کار را نشان میدهد.
tuple1 = (1, 2, 3)
tuple2 = (10, 20, 30)
print(dict (zip(tuple1,tuple2)))
خروجی قطعه کد بالا به شرح زیر است:
{1: 10, 2: 20, 3: 30}
17- بازگرداندن چند مقدار از توابع
برخی مواقع محاسبههای مختلفی در یک تابع انجام میشود و نیاز داریم چند مقدار به عنوان خروجی تابع بازگردانده شود. قطعه کد زیر نحوهی انجام اینکار را نشان میدهد.
def x():
return 1, 2, 3, 4
a, b, c, d = x()
print(a, b, c, d)
18- تعویض مقادیر دو متغیر بدون نیاز به استفاده از متغیر سوم
یکی از عوامل مهمی که باعث افزایش یا کاهش سرعت اجرای برنامههای کاربردی میشود، استفادهی بهینه از متغیرها است. هر متغیری که درون یک برنامه تعریف میکنید، نیازمند حافظه است. برنامهنویسان پایتون، از روشهای مختلفی برای این منظور استفاده میکنند. اگر نیاز دارید مقدار دو متغیر را بدون استفاده از متغیر سومی تغییر دهید، نحوهی انجام این کار به شرح زیر است:
num1, num2 = 10, 20
print(num1, num2)
num1, num2 = num2, num1
print(num1, num2)
19- ارسال مقادیر یک لیست به عنوان آرگومانهای متد
ما میتوانیم تمام عناصر یک لیست را با استفاده از * استخراج کنیم:
my_list = [1, 2, 3, 4]
print(my_list) # [1, 2, 3, 4]
print(*my_list) # 1 2 3 4
تکنیک فوق در شرایطی مفید است که میخواهیم تمام عناصر یک لیست را به عنوان آرگومان متد ارسال کنیم.
def sum_of_elements(*arg):
total = 0
for i in arg:
total += i
return total
result = sum_of_elements(*[1, 2, 3, 4])
print(result) # 10
20- استخراج عناصر وسط لیست
اگر لیستی از مقادیر در اختیار دارید و تنها به مقادیر میانی لیست نیاز دارید، پایتون اجازه میدهد به سادهترین شکل به مقادیر موردنیاز دسترسی پیدا کنید.
_, *elements_in_the_middle, _ = [1, 2, 3, 4, 5, 6, 7, 8]
print(elements_in_the_middle) # [2, 3, 4, 5, 6, 7]
21- تکرار رشتهها بدون حلقه
برای تکرار برخی رشتههای ساده، لزومی به استفاده از حلقهندارید و قادر به انجام این کار به شکل سادهای هستید.
string = "Abc"
print(string * 5) # AbcAbcAbcAbcAb
22- ادغام دیکشنریها در یک خط
پایتون 3.9 به برنامهنویسان اجازه میدهد، دو دیکشنری را در یک خط با یکدیگر ادغام کنند. قطعه کد زیر نحوهی استفاده از قابلیت فوق را نشان میدهد:
first_dictionary = {'name': 'Fatos', 'location': 'Munich'}
second_dictionary = {'name': 'Fatos', 'surname': 'Morina',
'location': 'Bavaria, Munich'}
result = first_dictionary | second_dictionary
print(result)
# {'name': 'Fatos', 'location': 'Bavaria, Munich', 'surname': 'Morina'}
23- پیدا کردن ایندکس یک عنصر در یک تاپل
پایتون اجازه میدهد ایندکس یک عنصر تاپل را به شکل سادهای پیدا کنید. قطعه کد زیر نحوهی استفاده از حالت فوق را نشان میدهد:
books = ('Atomic habits', 'Ego is the enemy', 'Outliers', 'Mastery')
print(books.index('Mastery')) # 3
24- تبدیل یک رشته به لیستی از رشتهها
فرض کنید ورودی تابعی را دریافت میکنید که یک رشته است، اما قرار است یک لیست باشد:
input = "[1,2,3]"
با اینحال، به قالب فوق نیازی ندارید و به جای آن به یک لیست نیاز دارید:
input = [1,2,3]
یا شاید پاسخی را بر مبنای فراخوانی یکAPI به صورت زیر دریافت میکنید:
input = [[1, 2, 3], [4, 5, 6]]
به جای اینکه خود را با استفاده از عبارتهای با قاعده خسته کنید، تنها کاری که باید انجام دهید این است که ماژول ast را به برنامه import کنید و سپس متد آن که literal_eval نام دارد را فراخوانی کنید:
import ast
def string_to_list(string):
return ast.literal_eval(string)
این تمام آن کاری است که باید انجام دهید. اکنون نتیجه را به صورت یک لیست یا لیستی از لیستها، همانند حالت زیر دریافت میکنید:
import ast
def string_to_list(string):
return ast.literal_eval(string)
string = "[[1, 2, 3],[4, 5, 6]]"
my_list = string_to_list(string)
print(my_list) # [[1, 2, 3], [4, 5, 6]]