برنامه نویسی ۴۹۰۵ بازدید

در این نوشته به معرفی برخی از ترفندهای پایتون پرداخته‌ایم. پایتون یکی از محبوب‌ترین و پر تقاضاترین زبان‌های برنامه‌نویسی جهان محسوب می‌شود و این مسئله دلایل مختلفی دارد:

  • یادگیری پایتون آسان است
  • پایتون زبان کاملاً متنوعی است.
  • پایتون طیف وسیعی از ماژول‌ها و کتابخانه‌های مختلف دارد.

اغلب دانشمندان علم داده روزانه به عنوان یک بخش جدایی‌ناپذیر از شغلشان با پایتون کار می‌کنند. در این مسیر برخی نکات و ترفندها وجود دارند که می‌توانند به استفاده هر چه بهتر از پایتون کمک کنند. در این نوشته برخی کاربردی‌ترین از این موارد را به صورت یک راهنمای جامع با شما در میان گذاشته‌ایم. اغلب این ترفندها چیزهایی هستند که یک دانشمند علم داده در کاربرهای روزمره خود با آن‌ها مواجه می‌شود. برخی از آن‌ها با جستجوی مستندات کتابخانه استاندارد پایتون به دست آمده‌اند. برخی دیگر نیز با بررسی PyPi نوشته شده‌اند.

یکی از دلایل محبوبیت زیاد پایتون این است که زبانی خوانا و گویا محسوب می‌شود. در اغلب موارد به شوخی گفته می‌شود که پایتون شبه کدی است که قابلیت اجرایی دارد؛ اما هنگامی که کدی مانند زیر می‌نویسیم، مشاهده می‌کنیم که این گفته چقدر واقعیت دارد.

x = [True, True, False]

if any(x):
    print("At least one True")

if all(x):
    print("Not one False")

if any(x) and not all(x):
    print("At least one True and one False")

bashplotlib

اگر قصد دارید گراف‌هایی در کنسول ترسیم کنید،‌ می‌توانید از دستور زیر کمک بگیرید:

$ pip install bashplotlib
فیلم آموزشی مرتبط

Collections

پایتون انواع داده پیش‌فرض بسیار جالبی دارد؛ اما در برخی موارد این انواع داده آن چنان که از آن‌ها انتظار داریم عمل نمی‌کنند. خوشبختانه کتابخانه استاندارد پایتون ماژول collections را عرضه کرده است. این افزونه کارآمد انواع داده بیشتری را در اختیار ما قرار می‌دهد.

from collections import OrderedDict, Counter

# Remembers the order the keys are added!
x = OrderedDict(a=1, b=2, c=3)

# Counts the frequency of each character
y = Counter("Hello World!")

dir

آیا تا کنون کنجکاو شده‌اید که بدانید چگونه می‌توانید به درون یک شیء پایتون نگاه کنید و خصوصیات آن را ببینید؟ بدین منظور می‌توانید دستور زیر را در خط فرمان وارد کنید:

>>> dir()
>>> dir("Hello World")
>>> dir(dir)

این خصوصیت زمانی که به صورت تعاملی در حال اجرای پایتون هستید و همچنین برای کاوش دینامیک اشیا و ماژول‌هایی که با آن‌ها کار می‌کنید، بسیار مفید خواهد بود.

Emoji

با استفاده از این خصوصیت می‌توانید در پایتون از ایموجی‌ها استفاده کنید.

$ pip install emoji

طرز استفاده آن نیز به صورت زیر است:

from emoji import emojize
print(emojize(":thumbs_up:"))

from __future__ import

یکی از نتایج محبوبیت بالای پایتون آن است که همیشه نسخه‌های جدیدی در حال توسعه هستند. منظور از نسخه‌های جدید، امکانات و ویژگی‌های جدید هستند؛ مگر این که نسخه شما منسوخ شده باشد.

با این وجود جای نگرانی نیست. future__ module__ امکان ایمپورت کردن ویژگی‌های نسخه‌های بعدی پایتون را فراهم می‌سازد. این وضعیت شبیه سفر در زمان یا نوعی جادو است.

from __future__ import print_function
print("Hello World!")
فیلم آموزشی مرتبط

geopy

جغرافیا می‌تواند زمینه چالش‌برانگیزی برای برنامه‌نویس‌ها باشد. به همین جهت ماژول geopy برای تسهیل آن ارائه شده است.

$ pip install geopy

این ماژول یک لایه انتزاعی از API های سرویس‌های ژئوکدینگ مختلف ایجاد می‌کند و بدین ترتیب این ماژول امکان به دست آوردن آدرس کامل، طول و عرض جغرافیایی و حتی ارتفاع یک مکان مشخص را فراهم می‌سازد. همچنین یک کلاس مفید برای تعیین مسافت وجود دارد. این کلاس، مسافت بین دو نقطه را بر اساس معیار مورد نظر شما اندازه‌گیری می‌کند.

from geopy import GoogleV3

place = "221b Baker Street, London"
location = GoogleV3().geocode(place)

print(location.address)
print(location.location)

howdoi

اگر در یک مسئله کدنویسی متوقف شده‌اید و نمی‌توانید کدی را که قبلاً دیده بود به خاطر بیاورید، می‌توانید وب‌سایت StackOverflow را بررسی کنید؛ اما گر نمی‌خواهید محیط ترمینال را ترک کنید می‌توانید از howdoi به عنوان یک ابزار خط فرمان مفید استفاده کنید:

$ pip install howdoi

شما می‌توانید هر سؤالی که دارید از این ابزار بپرسید و این ابزار همه توان خود را برای یافتن بهترین پاسخ به کار می‌گیرد.

$ howdoi vertical align css
$ howdoi for loop in java
$ howdoi undo commits in git

این ابزار پاسخ‌های خود را با بررسی بهترین پاسخ‌های وب‌سایت StackOverflow به دست می‌آورد. دقت کنید که این ابزار ممکن است در همه موارد مفیدترین اطلاعات را ارائه نکند.

$ howdoi exit vim

Inspect

ماژول inspect پایتون برای درک آن چه در پشت پرده آن رخ می‌دهد، بسیار مناسب است. شما حتی می‌توانید متدهای آن را روی خودش فراخوانی کنید.

نمونه کد زیر از متد ()inspect.getsource برای نمایش سورس کد خود استفاده می‌کند. همچنین از متد ()inspect.getmodule برای نمایش ماژولی که در آن تعریف شده استفاده می‌کند. خط آخر کد، شماره همان خط را نمایش می‌دهد.

import inspect

print(inspect.getsource(inspect.getsource))
print(inspect.getmodule(inspect.getmodule))
print(inspect.currentframe().f_lineno)

البته علاوه بر این کاربردهای آزمایشی، ماژول inspect می‌تواند برای درک آن چه کد شما انجام می‌دهد نیز مفید باشد و می‌توان از آن برای نوشتن کدهای خود-مستند استفاده کرد.

Jedi

کتابخانه Jedi یک کتابخانه تکمیل خودکار و تحلیل کد است که موجب سریع‌تر شدن و افزایش بهره‌وری کدنویسی می‌شود.

اگر کد خود را در یک IDE نمی‌نویسید، احتمالاً به استفاده از Jedi به عنوان یک افزونه ویرایشگر علاقه‌مند خواهید بود. با این وجود احتمالاً شما قبلاً نیز از Jedi استفاده کرده‌اید. پروژه IPython از Jedi برای کارکرد تکمیل خودکار کد استفاده می‌کند.

فیلم آموزشی مرتبط

kwargs**

موقعی که اقدام به یادگیری یک زبان جدید می‌کنیم، معیارهای مختلفی هستند که باید در این مسیر پشت سر بگذاریم. در مورد پایتون، درک دستور زبان پیچیده kwargs** مسلماً یکی از این معیارها محسوب می‌شود.

دو ستاره جلوی شیء دیکشنری امکان ارسال محتوای آن دیکشنری به صورت آرگومان‌های دارای نام به یک تابع را فراهم می‌سازد.

کلیدهای دیکشنری نام‌های آرگومان هستند و مقادیر نیز همان مقدارهای ارسالی به تابع محسوب می‌شوند. می‌بینید که حتی لازم نیست که آن را kwargs بنامیم.

dictionary = {"a": 1, "b": 2}

def someFunction(a, b):
   print(a + b)
   return

# these do the same thing:
someFunction(**dictionary)
someFunction(a=1, b=2)

این وضعیت در مواردی که می‌خواهیم تابع‌هایی برای مدیریت آرگومان‌های دارای نام و تعریف نشده از قبل را مدیریت کنیم مفید خواهد بود.

List comprehensions

یکی از محبوب‌ترین چیزها در برنامه‌نویسی پایتون «خلاصه لیست» (List comprehensions) محسوب می‌شود.

این عبارت‌ها موجب تسهیل نوشتن کد بسیار تمیز می‌شوند که مانند یک زبان معمولی خوانده می‌شود. در مورد روش استفاده از خلاصه لیست‌ها در پایتون می‌توانید در مقاله «List Comprehension در پایتون چیست و چه زمانی باید از آن استفاده کنیم؟» بیشتر مطالعه کنید.

numbers = [1,2,3,4,5,6,7]
evens = [x for x in numbers if x% 2 is 0]
odds = [y for y in numbers if y not in evens]

cities = ['London', 'Dublin', 'Oslo']

def visit(city):
   print("Welcome to "+city)

for city in cities:
   visit(city)

map

پایتون از طریق ویژگی‌های داخلی خود از برنامه‌نویسی تابعی نیز پشتیبانی می‌کند. یکی از مفیدترین تابع‌ها در این زمینه map() است که به طور خاص در ترکیب با تابع‌های لامبدا عمل می‌کند.

x = [1, 2, 3]
y = map(lambda x: x + 1, x)

# prints out [2,3,4]
print(list(y))

در مثال فوق ()map یک تابع لامبدا ساده روی هر عنصر در x اعمال می‌کند. بدین ترتیب یک شیء map بازگشت می‌یابد که می‌تواند به نوعی شیء قابل تکرار مانند لیست یا چندتایی تبدیل شود.

فیلم آموزشی مرتبط

newspaper3k

اگر قبلاً با این ماژول آشنا نشده‌اید باید خود را آماده کنید که با عجیب‌ترین ماژول مقالات در پایتون (+) مواجه شوید.

این ماژول امکان بازیابی مقاله‌های جدید و متا داده مرتبط با آن را از طیفی از انتشارات بین‌المللی معتبر فراهم می‌سازد. با استفاده از این ماژول شما می‌توانید تصاویر، متن و نام نویسنده‌های مقالات را بازیابی کنید. این ماژول حتی برخی قابلیت‌های NLP را نیز دارد.

بنابراین اگر در فکر استفاده از BeautifulSoup با هر نوع کتابخانه وب اسکرپینگ دیگر در پروژه‌های خودتان هستید، می‌توانید به جای آن با دستور زیر این ماژول را نصب کرده و در وقت خود صرفه‌جویی کنید.

 $ pip install newspaper3k

Operator overloading

پایتون از Operator overloading پشتیبانی می‌کند. شاید فکر کنید Operator overloading اصطلاحی است که باعث می‌شود شما یک دانشمند خبره در زمینه علوم رایانه به نظر بیایید؛ اما مفهوم آن کاملاً ساده است.

آیا تا کنون از خود پرسیده‌اید که پایتون چگونه از علامت + هم برای جمع زدن اعداد و هم الحاق رشته‌ها استفاده می‌کند. این مفهوم عملی Operator overloading است.

بدین ترتیب شما می‌توانید شی‌ءهایی تعریف کنید که نمادهای استاندارد پایتون به روش خاص خود با آن‌ها تعامل داشته باشند. با استفاده از این امکان، هر شیء بر اساس زمینه‌ای که در آن قرار دارد، مورد تعامل قرار می‌گیرد.

class Thing:
    def __init__(self, value):
        self.__value = value
    def __gt__(self, other):
        return self.__value > other.__value
    def __lt__(self, other):
        return self.__value < other.__value something = Thing(100) nothing = Thing(0) # True something > nothing

# False
something < nothing

# Error
something + nothing

pprint

تابع پیش‌فرض print پایتون کار خود را به خوبی انجام می‌دهد؛ اما اگر بخواهید هر گونه شیء تو در توی بزرگ را نمایش دهید، احتمالاً با نتیجه‌ای زشت مواجه شده‌اید.

اما یک ابزار دیگر به نام کتابخانه pretty-print نیز در پایتون وجود دارد که با استفاده از آن می‌توانید شی‌ءهای دارای ساختار پیچیده را در قالبی خوانا نمایش دهید.

این کتابخانه یک ابزار مفید است که هر توسعه‌دهنده‌ای که با ساختمان‌های داده بزرگ سر و کار دارد باید با آن آشنا باشد.

import requests
import pprint

url = 'https://randomuser.me/api/?results=1'
users = requests.get(url).json()

pprint.pprint(users)

Queue

پایتون از چند نخی پشتیبانی می‌کند و این فرایند به وسیله ماژول Queue در کتابخانه استاندارد اجرا می‌شود. این ماژول امکان پیاده‌سازی ساختمان داده صف را فراهم ساخته است. این‌ها ساختمان‌های داده‌ای هستند که امکان افزودن و بازیابی مدخل را بر اساس قاعده‌های خاص میسر می‌سازند.

صف‌های «ورودی اول، خروجی اول» یا FIFO امکان بازیابی اشیا را به ترتیبی که اضافه شده‌اند فراهم می‌سازند. صف‌های «خروجی آخر، ورودی اول» یا LIFO امکان دسترسی به جدیدترین شیءهای افزوده شده به صف را فراهم می‌کند.

در نهایت صف‌های اولویت امکان بازیابی صف‌ها بر اساس ترتیبی که مرتب‌سازی شده است را میسر می‌سازند.

فیلم آموزشی مرتبط

__repr__

هنگام تعریف کردن یک شیء در پایتون، ارائه یک روش رسمی برای بازنمایی آن شیء به صورت رشته مفید خواهد بود. برای نمونه:

>>> file = open('file.txt', 'r')
>>> print(file)
<open file 'file.txt', mode 'r' at 0x10d30aaf0>

راهبرد فوق موجب سهولت زیادی در دیباگ کردن کد می‌شود. این کد را به صورت زیر به تعریف کلاس اضافه کنید:

class someClass:
    def __repr__(self):
        return ""

someInstance = someClass()

# prints 
print(someInstance)

sh

پایتون یک زبان اسکریپت‌نویسی عالی است؛ اما در برخی موارد استفاده از کتابخانه‌های استاندارد سیستم عامل می‌تواند دشوار باشد. کتابخانه sh یک جایگزین مناسب محسوب می‌شود. این کتابخانه امکان فراخوانی هر برنامه‌ای را به صورتی فراهم می‌سازد که گویا یک تابع دلخواه است و برای امور خودکارسازی گردش کارها و وظایف در درون پایتون بسیار مفید است.

import sh

sh.pwd()
sh.mkdir('new_folder')
sh.touch('new_file.txt')
sh.whoami()
sh.echo('This is great!')

سرنخ‌های نوع (Type hints)

پایتون یک زبان با نوع‌بندی دینامیک است. در این زبان نیازی به تعریف صریح نوع داده‌ها هنگام تعریف کردن متغیرها، تابع‌ها، کلاس‌ها و موارد دیگر وجود ندارد.

بدین ترتیب امکان توسعه سریع‌تر کد فراهم می‌شود. با این وجود چیزی آزاردهنده‌تر از خطای زمان اجرا به دلیل یک نوع‌بندی نامناسب در زمان کدنویسی به نظر نمی‌رسد.

از پایتون 3.5 به بعد امکان ارائه سرنخ‌هایی در مورد نوع داده در زمان تعریف تابع‌ها فراهم شده است.

def addTwo(x: Int) -> Int:
   return x + 2

همچنین می‌توان نام‌های مستعاری برای نوع داده ارائه کرد:

from typing import List

Vector = List[float]
Matrix = List[Vector]

def addMatrix(a : Matrix, b : Matrix) -> Matrix:
  result = []
  for i,row in enumerate(a):
    result_row =[]
    for j, col in enumerate(row):
      result_row += [a[i][j] + b[i][j]]
    result += [result_row]
  return result

x = [[1.0, 0.0], [0.0, 1.0]]
y = [[2.0, 1.0], [0.0, -2.0]]

z = addMatrix(x, y)

با این که «حاشیه‌نویسی برای نوع» (type annotations) اجباری نیست؛ اما باعث می‌شود که درک کد آسان‌تر شود.

همچنین امکان استفاده از ابزارهای بررسی نوع برای مشخص ساختن خطاهای TypeErrors پیش از زمان اجرا را فراهم می‌کند. این ابزار در صورتی که روی پروژه‌های بزرگ و پیچیده کار می‌کنید، بسیار ارزشمند خواهد بود.

فیلم آموزشی مرتبط

Uuid

این ابزار یک روش ساده و سریع برای ایجاد ID-های یکتای سراسری ارائه می‌کند که UUID نیز نامیده می‌شود. این ID-ها از طریق ماژول uuid کتابخانه استاندارد پایتون میسر است.

import uuid

user_id = uuid.uuid4()
print(user_id)

این ماژول یک عدد 128 بیتی تصادفی ایجاد می‌کند که تقریباً می‌توان مطمئن بود منحصر به فرد است. در واقع 2¹²² UUID ممکن را می‌توان با این ماژول ساخت. این مقدار بالغ با 5 آندسیلیون یا 5,000,000,000,000,000,000,000,000,000,000,000,000 است.

احتمال یافتن موارد تکراری در مجموعه مفروض کاملاً پایین است. حتی اگر یک تریلیون UUID ایجاد کنید، باز هم امکان یافتن موارد تکراری کمتر از یک در میلیارد خواهد بود. این عملکرد برای یک قطعه کد دو خطی کاملاً مطلوب است.

محیط‌های مجازی (Virtual Environments)

مسلماً محیط‌های مجازی یکی از خصوصیات پایتون است که محبوب بسیاری از توسعه‌دهندگان است. در موارد زیادی ما مجبور هستیم، همزمان روی چند پروژه پایتون کار کنیم و متأسفانه در پاره‌ای موارد دو پروژه به نسخه‌های متفاوتی از یک وابستگی نیاز دارند. اینک باید کدام نسخه را روی سیستم نصب کنیم؟

خوشبختانه پایتون از محیط‌های مجازی پشتیبانی می‌کند و می‌توان هر دو نسخه را همزمان روی سیستم داشت. کافی است در خط فرمان دستورهای زیر را وارد کنید:

python -m venv my-project
source my-project/bin/activate
pip install all-the-modules

اکنون می‌توانیم نسخه‌های مستقلی از نصب‌های پایتون را داشته باشیم که روی یک ماشین منفرد اجرا می‌شوند.

ویکی‌پدیا (Wikipedia)

ویکی‌پدیا یک API عالی دارد که امکان دسترسی برنامه‌نویسی شده به متون عالی را فراهم می‌سازد و منبع کاملاً رایگانی از دانش و اطلاعات است. ماژول ویکی‌پدیا باعث شده است که دسترسی به این اطلاعات کاملاً ساده شود.

import wikipedia

result = wikipedia.page('freeCodeCamp')
print(result.summary)
for link in result.links:
   print(link)

این ماژول مانند سایت واقعی ویکی‌پدیا از چند زبان مختلف، صفحه‌های ابهام‌زدایی، بازیابی صفحه‌های تصادفی و حتی متد ()donate پشتیبانی می‌کند.

Xkcd

شوخ‌طبعی یکی از خصوصیات کلیدی زبان برنامه‌نویسی پایتون است و در نهایت باید اشاره کنیم که نام این زبان از یک نمایش کمدی انگلیسی به نام «سیرک پرنده مانتی پایتان» (Monty Python's Flying Circus) گرفته شده است. در اغلب بخش‌های مستندات رسمی پایتون، اشاره‌هایی به این نمایش کمدی صورت گرفته است.

این حس شوخ‌طبعی به مستندات پایتون محدود نمی‌شود و برای نمونه اگر دستور زیر را وارد کنید می‌توانید با بخش‌های دیگری از آن روبرو شوید:

import antigravity

پایتون هرگز تغییر نمی‌کند.

فیلم آموزشی مرتبط

YAML

YAML که اختصاری برای «YAML Ain’t Markup Language» خوانده می‌شود، یک زبان قالب‌بندی داده‌ها است که JSON زیرمجموعه آن محسوب می‌شود. برخلاف جیسون، YAML می‌تواند شیءهای پیچیده‌تری را ذخیره کنید و به عناصر خودش اشاره کند. همچنین می‌توانید توضیحاتی بنویسید که آن را به طور خاص برای نوشتن فایل‌های پیکربندی مناسب می‌سازد.

ماژول PyYAML امکان استفاده از YAML به همراه پایتون را فراهم ساخته است. آن را با دستور زیر می‌توانید نصب کنید:

$ pip install pyyaml

و سپس آن را در پروژه‌های خود ایمپورت کنید:

import yaml

PyYAML امکان ذخیره‌سازی شی‌ءهای پایتون با هر نوع داده‌ای را می‌دهد و وهله‌هایی از هر کلاس تعریف شده از سوی کاربر را می‌توان با استفاده از آن ذخیره کرد.

Zip

آخرین ترفندی که در این نوشته مطرح می‌کنیم و کاملاً جذاب است به بحث ایجاد دیکشنری از دو لیست مربوط است.

keys = ['a', 'b', 'c']
vals = [1, 2, 3]
zipped = dict(zip(keys, vals))

تابع توکار ()zip چند شیء تکرارپذیر می‌پذیرد و یک لیست از چندتایی‌ها بازمی‌گرداند. هر چندتایی گروهی از عناصر شیءهای ورودی را بر اساس اندیس‌های موقعیتشان شامل می‌شود. همچنین می‌توانید اشیا را با فراخوانی متد ()zip* روی آن‌ها از حالت فشرده خارج کنید (unzip).

سخن پایانی

بدین ترتیب به پایان راهنمای جامع ترفندهای پایتون می‌رسیم که احتمالاً در پروژه‌های خودتان می‌توانید بهره‌های زیادی از آن بگیرید. پایتون یک زبان کاملاً متنوع و توسعه‌یافته محسوب می‌شود و از این رو ویژگی‌های زیادی دارد که نمی‌توان در یک مقاله با این حجم به همه آن‌ها پرداخت.

اگر این مطلب برایتان مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۸ نفر
آیا این مطلب برای شما مفید بود؟
شما قبلا رای داده‌اید!
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.

«میثم لطفی» در رشته‌های ریاضیات کاربردی و مهندسی کامپیوتر به تحصیل پرداخته و شیفته فناوری است. وی در حال حاضر علاوه بر پیگیری علاقه‌مندی‌هایش در رشته‌های برنامه‌نویسی، کپی‌رایتینگ و محتوای چندرسانه‌ای، در زمینه نگارش مقالاتی با محوریت نرم‌افزار با مجله فرادرس همکاری دارد.