یکی از دلایل محبوبیت زبان برنامهنویسی پایتون قابلیت خوانایی و نزدیک بودن آن به زبان انگلیسی است به طوری که اغلب اوقات کدنویسی با این زبان به مانند این است که بخواهیم یکسری به اصطلاح Pseudocode (شِبهکُد) را اجرا کنیم که در همین راستا در این مقاله قصد داریم تا برخی از کاربردیترین ماژولهای زبان پایتون به همراه چند مورد از فیچرهای محبوب این زبان را معرفی کنیم.
فانکشنهای ()all و ()any
این فانکشنها به صورت اصطلاحاً Built-in در زبان برنامهنویسی پایتون تعریف شدهاند که عملکرد آنها را در قالب مثال زیر بیان میکنیم:
x = [True, True, False]
print(any(x))
print(all(x))
print(any(x) and not all(x))
فانکشنهای ()any
و ()all
به منظور انجام عملیات منطقی AND
و OR
بر روی مقادیر یک آرایه مورد استفاده قرار میگیرند. همانطور که در مثال بالا میبینید، آرایهای به نام x
با سه مقدار داریم که در خط دوم گفتهایم فانکشن ()any
به ازای دریافت مقادیر این آرایه در صورتی مقدار True
را در خروجی چاپ کند که حداقل یکی از مقادیر آرایه True
باشد که این به معنای انجام عملیات منطقیِ OR
روی آرایۀ مد نظر است.
در خط سوم نیز گفتهایم که اگر چنانچه تمامی مقادیر آرایه True
بود، در خروجی مقدار True
را چاپ کند که به منزلۀ انجام عملیات منطقیِ AND
روی مقادیر آرایه است و دستور خط چهارم نیز در شرایطی مقدار True
را در خروجی چاپ میکند که حداقل یکی از مقادیر آرایه True
یا False
باشد و نه همۀ آنها. به عبارتی، در شرایطی که حداقل یکی از مقادیر این آرایه مخالف مابقی مقادیر آن باشد، خروجی مقدار True
خواهد بود که به منزلۀ انجام عملیات منطقی XOR
است.
bashplotlib
این لایبرری امکان ترسیم نمودار و به اصطلاح ویژولایز کردن دیتا را در محیط کنسول برای دولوپرها فراهم میکند که نصب آن از طریق کامند زیر صورت میگیرد:
$ pip install bashplotlib
و سپس آن را در برنامۀ خود بدین شکل ایمپورت میکنیم:
import bashplotlib
در ادامه با بهکارگیری فانکشن زیر، میتوانیم نمودارهایی از جمله یک نمودار از نوع اِسکاتر و یا هیستوگرام مربوط به دیتای مد نظر را رسم نماییم:
plot_scatter(f, xs, ys, size, pch, colour, title)
که آرگومانها به ترتیب فایل مربوط به دیتای مد نظر برای مشخص کردن مختصات محورهای x و y، آرگومان مربوط به مختصات x در شرایطی که مختصات مشخصی در فایل اصلی بیان نشده باشد، آرگومان مربوط به مختصات y، اندازۀ کلی نمودار، شکل نقاط روی نمودار، رنگ نقاط و عنوان اصلی نمودار میباشد و برای رسم هیستوگرام نیز از دستور زیر استفاده میکنیم:
plot hist(f, height=20.0, bincount=None, pch='o', colour='white', title='', xlab=None, nosummary=True)
که در آن هر یک از آرگومانها به ترتیب فایل دیتای مد نظر، ارتفاع نمودار بر حسب تعداد خطوط، تعداد هر یک از ستونهای نمودار، شکل ستونهای نمایش دادهشده در محیط ترمینال، رنگ آنها، عنوان نمایش دادهشده در بالای نمودار، xlab
به منظور نمایش یا عدم نمایش لیبل مربوط به محور x و nosummary
برای نمایش یا عدم نمایش محور y به کار میروند.
collections
زبان برنامهنویسی پایتون به صورت پیشفرض یکسری دیتا تایپ از جمله int
(مقادیر عددی صحیح)، float
(عدد اعشاری)، str
(مقادیر اِسترینگ یا رشتهای)، list
(دنبالهای از مقادیر در قالب لیست) و غیره را دارد اما این در حالی است که ماژولی تحت عنوان collections
امکان ارائۀ دیتا تایپهای بیشتری را برای دولوپرها فراهم میکند به طوری که داریم:
from collections import OrderedDict, Counter
# Remembers the order the keys are added!
x = OrderedDict(a= 5, b=4, c=9)
# Counts the frequency of each character
y = Counter("Hello World!")
در کُد بالا ابتدا از ماژول collections
کلاسهای OrderedDict
و Counter
را ایمپورت کرده و در ادامه در خط سوم آبجکتی از روی کلاس OrderedDict
تحت عنوان x
ساختهایم که این آبجکت یک نوع دادۀ دیکشنری با کلیدهای b
،a
و c
(دقیقاً به همان ترتیب بیانشده به عنوان ورودی) ایجاد کند که در آنها مقادیر نیز برابر با مقادیر ذکرشده در مقابل کلیدها خواهند بود. در خط پنجم از روی کلاس Counter
آبجکتی تحت عنوان y
ساختهایم که این کلاس تعداد تکتک حروف بهکاررفته در عبارت مشخصشده را در خروجی ریترن کرده و در متغیر y
ذخیره میکند.
()dir
این فانکشن از پیش تعریفشده در پایتون، لیستی از اتربیوتها و متدهای بهکاررفته در داخل یک آبجکت را ریترن میکند. برای مثال در کد زیر داریم:
import struct
dir()
dir(struct)
dir(dir)
همانطور که در کد فوق میبینید، ماژولی دلخواه را در ابتدا ایمپورت کرده سپس فانکشن ()dir
را اجرا میکنیم. این فانکشن تمامی اتربیوتهای مربوط به ماژولهای اِسکوپ جاری را در اختیار ما قرار خواهد داد اما در خط سوم نام ماژول struct
را به عنوان آرگومان ورودی به این فانکشن دادهایم که منجر بدین خواهد شد تا تمامی اتربیوتهای بهکاررفته در ماژول مذکور را در خروجی ریترن کند. در خط چهارم نیز خود کلیدواژهٔ dir
را به عنوان آرگومان ورودی به این فانکشن دادهایم که بدین وسیله تمامی متدها، آبجکتها و اتربیوتهای بهکاررفته در فانکشن ()dir
در معرض دید ما قرار خواهد گرفت.
emoji
این ماژولی است که امکانی را در اختیار دولوپرها قرار میدهد تا بتوانند با استفاده از زبان برنامهنویسی پایتون، ایموجی مد نظر خود را در خروجی به نمایش در آورند. در همین راستا، ابتدا باید ماژول مذکور را دانلود و نصب کنید که برای این منظور کامند زیر را اجرا میکنیم:
$ pip install emoji
در ادامه کلاس emojize
از ماژول مذکور را ایمپورت کرده و در خط دوم آبجکتی تحت عنوان thum
روی این کلاس میسازیم به طوری که کُد مربوط به ایموجی 👍 را به عنوان آرگومان ورودی به این کلاس داده و در خط سوم از برنامه خواستهایم تا نتیجۀ حاصل از اجرای این کلاس که در آبجکت thum
نگاهداری میشود را در خروجی چاپ کند:
from emoji import emojize
thum = emojize(":thumbs_up:")
print(thum)
در نهایت ایموجی 👍 توسط فانکشن ()print
چاپ خواهد شد.
from __future__ import
پایتون ماژولی تحت عنوان __future__
دارا است که این امکان را در اختیار دولوپرها قرار میدهد تا بتوانند ماژولها، متدها و لایبرریهای مد نظر خود را به گونهای تعریف کنند تا در نسخههای آیندۀ این زبان امکان اجرای اپلیکیشن روی فیچرهای جدید ارائهشده برای ماژولها، متدها و لایبرریهای مذکور فراهم شود که بهکارگیری از این ماژول منجر بدین خواهد شد تا اپلیکیشن مد نظر تا حدود زیادی با قابلیتهای نسخۀ جدید این زبان به اصطلاح Compatible (سازگار) باشد. برای مثال داریم:
from __future__ import print_function
print("Hello World!")
همانطور که در کد بالا مشاهده میکنید، در خط اول کلاس print_function
از ماژول __future__
را ایمپورت کردهایم و بدین ترتیب فانکشن ()print
بر اساس آخرین فیچرهای ارائهشده برای این فانکشن اجرا خواهد شد که در خط دوم نیز فانکشن مذکور بر اساس قابلیتهای جدیدش، استرینگ ورودیِ !Hello World را چاپ خواهد کرد.
geopy
این ماژول امکانی را در اختیار وب دولوپرها قرار میدهد تا بتوانند با بهکارگیری از یکسری API به اصطلاح Third Party دادههایی همچون مختصات آدرس شهر، کشور و محل مورد نظر خود در سراسر جهان را بیابند (برای آشنایی بیشتر با مفهوم API، به آموزش API چیست؟ مراجعه نمایید.) همچنین این ماژول کلاسی تحت عنوان distance
دارا است که قابلیت محاسبۀ فاصلۀ بین دو مکان را بر اساس واحد اندازهگیری مد نظر دولوپر عرضه میکند. ابتدا با تایپ دستور زیر در کامندلاین، ماژول مذکور را دانلود و نصب میکنیم:
$ pip install geopy
در ادامه قصد داریم تا با اتصال به ایپیآی مربوط به سرویس گوگلمَپ، آدرس دقیق مکان مد نظر خود را بیابیم که در همین راستا کلاسی تحت عنوان GoogleV3
از ماژول مذکور را ایمپورت کرده و در ادامه منطقۀ مد نظر خود را در متغیری تحت عنوان place
ذخیره میکنیم:
from geopy import GoogleV3
place = "221b Baker Street, London"
location = GoogleV3().geocode(place)
print(location.address)
در خط سوم آبجکتی تحت عنوان location
از روی کلاس GoogleV3
ساخته و متغیر place
را به عنوان آرگومان ورودی به فانکشن ()geocode
از این کلاس میدهیم تا در نهایت در خط چهارم آدرس دقیق مد نظر ما را توسط فانکشن ()print
در خروجی چاپ کند.
howdoi
این ماژول امکانی را برای دولوپرها فراهم میکند تا بدین وسیله بتوانند به پاسخ برخی سؤالات خود دست یابند به طوری که ایشان بدون ترک محیط ترمینال میتوانند جواب پرسشهای خود را در استک اورفلو جستجو کنند اما باید به خاطر داشته باشیم که این ماژول پاسخ سؤالات را از میان بهترین پاسخهای ارائهشده در استک اورفلو برای ما به نمایش در خواهد آورد و ممکن است همواره مفیدترین سولوشن عرضه نگردد! برای دانلود و نصب این ماژول نیز دستور زیر را در کامندلاین تایپ میکنیم:
$ pip install howdoi
حال اقدام به تست این ماژول میکنیم:
howdoi vertical align css
howdoi for loop in java
howdoi undo commits in git
همانطور که در ادامه میبینید، با استفاده از دستورهایی همچون آنچه در بالا مشاهده میکنید، میتوان به پاسخ برخی از سؤالات مد نظر خود دست پیدا کرد.
inspect
این ماژول قابلیتی را برای دولوپرها فراهم میکند تا بتوانند آنچه که در پشت صحنۀ یک برنامه، متد و یا کُد اتفاق میافتد را درک کنند و نیاز به توضیح نیست که با فراخوانی خودِ ماژول نیز میتوان نحوۀ کار متدهای مربوط به این ماژول را مشاهده و درک کرد.
در نمونه کد زیر، ابتدا ماژول مذکور را ایمپورت کرده و به منظور چاپ و نمایش تمامی دیتای موجود در متد و یا لایبرری مد نظر از یک ماژول خاص مورد استفاده قرار گرفته که در اینجا کلاس algorithms
از ماژولی تحت عنوان networkx
را به عنوان آرگومان ورودی در نظر گرفتهایم که این ماژول به منظور بررسی و مدیریت گرافها و شبکههای پیچیده به کار گرفته میشود که برای این منظور نیز ابتدا باید کلاس مذکور را از ماژول مد نظر ایمپورت کنیم:
import inspect
from networkx import algorithms
print(inspect.getsource(algorithms))
print(inspect.getmodule(inspect.getmodule))
print(inspect.currentframe().f_lineno)
خط چهارم از کد فوق نیز این قابلیت را در اختیار دولوپرها قرار میدهد تا بتوانند در صورت نیاز مشخص کنند که یک لایبرری، متد یا الگورریتم خاص به چه ماژولی تعلق دارد و در نهایت خط پنجم نیز شمارۀ خط جاری مربوط به اجرای این قطعه کُد را در خروجی چاپ میکند (از جمله دیگر ویژگیهای مهم ماژول inspect
میتوان به درک نحوۀ کار برنامه و همچنین امکان نوشتن مستندات مربوط به نرمافزار اشاره کرد.)
jedi
این لایبرری امکان آنالیز و تکمیل خودکار کُد را برای دولوپرها فراهم میکند و همچنین منجر به افزایش سرعت و بهرهوری در کدنویسی میشود به علاوه اینکه دولوپرها میتوانند این لایبرری را به عنوان افزونهای در IDE خود مورد استفاده قرار دهند (نیاز به توضیح است که پروژهٔ IPython نیز برای توسعۀ اپلیکیشنهای خود از این لایبرری به عنوان ابزاری برای افزودن قابلیت تکمیل خودکار کد یا اصطلاحاً Autocompletion استفاده میکند.)
kwargs**
در پروسۀ یادگیری هر زبان برنامهنویسی نقاط عطف زیادی در طی مسیر وجود دارد که در مورد زبان برنامهنویسی پایتون نیز درک سینتکس kwargs**
احتمالاً به عنوان یکی از این نقاط عطف به شمار میرود که دو ستاره در کنار یک آبجکت از نوع دادۀ دیکشنری، این امکان را برای دولوپرها فراهم میکند تا بتوانند محتویات آن دیکشنری را به عنوان آرگومانهای ورودی به یک فانکشن پاس دهند.
در واقع، کلیدها در این دیکشنری به عنوان نام آرگومانهای ورودی به فانکشن پاس داده میشوند و مقادیر متناظر با هر یک از این کلیدها به عنوان مقدار ورودی به این فانکشن پاس داده شده و بدین طریق فانکشن مذکور فراخوانی شده و اجرا میشود. همانطور که در کد زیر میبینیم، ابتدا یک آبجکت از نوع دادۀ دیکشنری تحت عنوان dictionary
ساخته و دو آیتم در آن قرار دادیم که a
و b
کلید بوده و اعداد 1 و 2 به ترتیب مقادیر متناظر آنها هستند:
dictionary = {"a": 1, "b": 2}
def sum(a, b):
print(a + b)
return
# these do the same thing:
sum(a = 1, b = 2)
sum(**dictionary)
در ادامه فانکشنی تحت عنوان ()sum
تعریف کردهایم که در آن گفتهایم مقادیر a
و b
را با هم جمع کرده و در نهایت حاصل جمع را چاپ کند. حال برای فراخوانی فانکشن مذکور دو روش را میتوانیم در پیش بگیریم. روش اول که رویکرد رایجی برای فراخوانی فانکشنها میباشد، همانند دستور خط ششم، گفتهایم که به ازای دو آرگومان عددیِ 1 و 2 فانکشن ()sum
فراخوانی شده و این دو عدد را با هم جمع کرده و نتیجه را در خروجی چاپ کند.
اما روش دوم بدین صورت است که نوع دادۀ دیکشنری تعریفشده را به عنوان آرگومان ورودی به فانکشن مد نظر پاس دهیم که برای این منظور نیز میتوانیم نام دیکشنری مذکور را به همراه دو علامت **
به این فانکشن بدهیم و همانطور که در دستور خط هفتم مشاهده میکنید، از فانکشن ()sum
خواستهایم تا مقادیر منتسب به متغیر dictionary
را به عنوان مقدار ورودی دریافت کرده و آنها را باهم جمع کند و نتیجه را در خروجی چاپ کند. در واقع، این ماژول برای زمانی مفید است که دولوپرها بخواهند فانکشنی بنویسند که خود این فانکشن قابلیت نامگذاری آرگومانهای ورودی را داشته باشد که از قبل نامگذاری نشدهاند.
استفاده از دیتا تایپ list
زبان برنامهنویسی پایتون این قابلیت را دارا است تا دستورهای کدنویسی در آن به شکلی کاملاً واضح و تمیز نوشته شوند به طوری که بسیار نزدیک به زبان گفتار خوانده میشود که برای مثال در کد زیر از دیتا تایپ (نوع داده) لیست استفاده کردهایم و همانطور که مشاهده میکنید، ابتدا یک متغیر از نوع لیست تحت عنوان numbers
ساخته و مقادیر مد نظر را در آن ذخیره کردهایم:
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]
در ادامه، متغیری تحت عنوان evens
تعریف کردهایم که تمامی مقادیر داخل لیست به شرط آنکه باقیماندۀ تقسیم هر یک از این مقادیر بر عدد دو برابر با صفر باشد، در این متغیر ذخیره میشود؛ به عبارت بهتر، این متغیر تمامی مقادیر زوج از لیست مذکور را نگاهداری میکند و در خط سوم نیز گفتهایم که تمامی مقادیر موجود در لیست منهای مقادیر ذخیرهشده در متغیر evens
را ذخیره کند به طوری که این متغیر تمامی مقادیر فرد موجود در لیست را نگاهداری میکند.
در مورد قطعه کد زیر باید بگوییم که ابتدا متغیری از نوع لیست تحت عنوان cities
تعریف کرده و سه مقدار اِسترینگ را در آن ذخیره کردهایم و در ادامه فانکشنی تحت عنوان ()visit
تعریف کردهایم و پارامتری تحت عنوان city
را به عنوان آرگومان ورودی به این فانکشن پاس دادهایم و در خط سوم گفتهایم که آرگومان ورودی به این فانکشن، city
، با استرینگ «Welcome to» به اصطلاح کانکَت شده و توسط فانکشن ()print
چاپ شود:
cities = ['London', 'Dublin', 'Oslo']
def visit(city):
print("Welcome to "+city)
for cname in cities:
visit(cname)
حال در ادامه باید فانکشن تعریفشده را فراخوانی کنیم و برای اینکه این فانکشن به ازای تمامی مقادیر موجود در لیست cities
اجرا شود، باید متغیری تعریف کنیم تا قابلیت پیمایش این لیست را داشته باشد. بنابراین همانطور که در خط چهارم مشاهده میکنید، متغیری تحت عنوان cname
تعریف کرده و گفتهایم که تمامی مقادیر موجود در لیست cities
در این متغیر ذخیره شده و به ازای هر یک از آنها یک بار فانکشن ()visit
فراخوانی شود:
Welcome to London
Welcome to Dublin
Welcome to Oslo
که در نتیجۀ این فراخوانیها، سه عبارت فوق در خروجی چاپ خواهند شد.
map
زبان پایتون قابلیت برنامهنویسی فانکشنال را برای دولوپرها فراهم میکند که در همین راستا فانکشن ()map
یکی از بهترین فانکشنهای به اصطلاح Built-in در این زبان است که در ترکیب با فانکشنهای lambda
عملکرد بهتری ارائه میدهد (در توضیح فانکشن lambda
باید گفت که این کیوورد در زبان برنامهنویسی پایتون امکان نوشتن یکسری فانکشنهای به اصطلاح Anonymous یا «بینام» را برای دولوپرها فراهم میکند به طوری که ابتدا کیورد lambda
و به دنبال آن نام یکسری آرگومان ورودی مد نظر و در ادامه علامت :
و پس از آن نیز تنها دستور مُجاز برای اِعمال روی آرگومانهای ورودی مذکور نوشته میشود.)
در مورد نحوۀ عملکرد فانکشن ()map
نیز باید گفت که این فانکشن ابتدا یک آرایۀ جدید میسازد تا مقادیر حاصل از فراخوانی فانکشن مد نظر دولوپر به ازای هر یک از اِلِمانهای آرگومان ورودی را در آن ذخیره کند و به خاطر داشته باشیم که این متد مقادیر آرایۀ اصلی را تغییر نمیدهد:
x = [1, 2, 3]
z=lambda b : b + 1
y = map(z , x)
# prints out [2,3,4]
print(list(y))
همانطور در کد فوق مشاهده میکنید، ابتدا آرایهای تحت عنوان x
تعریف کردهایم که سه مقدار عددی در آن نگاهداری میشود و در ادامه فانکشن بینام lamba
را تعریف کردهایم که آن را به متغیری فرضی تحت عنوان z
منتسب نمودهایم و نیاز به توضیح نیست که ذکر این نام در تمامی نقاط برنامه به معنای فراخوانی فانکشن متناظر آن است. در ادامه متغیری تحت عنوان b
را به عنوان آرگومان ورودی به فانکشن بینام مذکور داده و گفتهایم دستور b+1
را به ازای هر یک از مقادیر ورودی اجرا کند. در واقع، این فانکشن هر مقداری را به عنوان ورودی دریافت کند آن را به علاوۀ عدد 1 کرده و در خروجی ریترن میکند.
حال نوبت به اِعمال فانکشن ()map
روی فانکشن بینام lambda
میرسد بدین معنی که ()map
فانکشن بینام منتسب به متغیر z
را به ازای تمامی مقادیر آرایۀ x
فراخوانی کرده و مقادیر حاصله را در آرایهای جدید تحت عنوان y
ذخیره میکند؛ به عبارت بهتر، فانکشن ()map
منجر بدین خواهد شد تا دستور x+1
به ازای تمامی مقادیر آرایۀ x
اجرا شده و در متغیر y
نگاهداری شوند و در ادامه این مقادیر با فانکشن از پیش تعریفشدۀ ()list
در قالب مقادیری از نوع دادۀ لیست در معرض دید ما قرار خواهند گرفت.
newspaper3k
این لایبرری در زبان پایتون امکانی را برای دولوپرها فراهم میکند تا بتوانند مقالات خبری و متادیتاهای مرتبط با آنها را از طیف وسیعی از نشریات بینالمللی موجود در وبسایتهای مختلف به اصطلاح پارس کرده و به دیتای آنها از جمله تصاویر، متن و نام نویسندگان دسترسی پیدا کنند. همچنین این لایبرری برخی از قابلیتهای NLP (پردازش زبان طبیعی) را به منظور بررسی مقالات مد نظر دارا است. برای دانلود و نصب این ماژول ابتدا دستور زیر را در کامندلاین اجرا میکنیم:
$ pip install newspaper3k
حال در ادامه قصد داریم تا یکی از مقالات منتشرشده در سکان آکادمی را با بهکارگیری از این ماژول مورد بررسی قرار دهیم و از همین روی ابتدا لایبرری Article
از این ماژول را ایمپورت میکنیم و همانطور که در کد زیر میبینید:
from newspaper import Article
url = 'https://sokanacademy.com/blog/9215/post'
article = Article(url)
article.download()
article.parse()
article.authors
آدرس مقالۀ مد نظر خود را در متغیری تحت عنوان url
ذخیره میکنیم و در خط سوم آبجکتی تحت عنوان article
از روی کلاس ()Article
ساخته و متغیر url
را به عنوان پارامتر ورودی به این فانکشن میدهیم و در ادامه و در خط چهارم فانکشن ()download
از این لایبرری را روی این آبجکت فراخوانی کرده و گفتهایم مقالۀ مد نظر از یوآرال مذکور را دانلود کند و در ادامه فانکشن ()parse
از این کلاس را روی آبجکت مذکور فراخوانی کرده و گفتهایم که این مقاله را پارس کرده و در نهایت در خط آخر از برنامه خواستهایم تا متاتگهای موجود در آن صفحۀ وب را بررسی کرده و مقدار متناظر با تگی تحت عنوان authors
در وبپیج مد نظر را در خروجی ریترن کند.
اپراتور اورلودینگ
زبان برنامهنویسی پایتون یکسری عملگرهایی دارا است که به صورت کلاسهای به اصطلاح Built-in در این زبان تعریف شدهاند که از جملۀ مهمترین عملگرها در این زبان میتوان موارد زیر را نام برد:
- ()add
- ()sub
- ()lt
- ()gt
که هر یک از آنها به ترتیب برای جمع دو عدد، تفریق دو عدد، چک کردن کوچکتر یا مساوی و چک کردن بزرگتر یا مساوی بودن دو عدد به کار میروند و هر یک از این کلاسها متدهای خاصی را دارند که در هنگام ساخت آبجکتی از روی کلاس مد نظر، این متدها فراخوانی میشوند که برای مثال میتوان به ترتیب متدهای زیر را نام برد:
- ()__add__
- ()__sub__
- ()__lt__
- ()__gt__
حال اگر بخواهیم رفتار هر یک از این عملگرها را تغییر دهیم، باید متدهایی که در هنگام ساخت آبجکت جدید از این کلاسها فراخوانی میشوند را متناسب با نیاز خود تغییر دهیم و برای این منظور کلاسی دلخواه تعریف کرده و متدهای مد نظر خود را در آن اصطلاحاً Overload میکنیم.
به طور مثال، در کد زیر قصد داریم تا رفتار متدهای ()lt
و ()gt
را تغییر دهیم و همانطور که ملاحظه میکنید، در ابتدا کلاسی تحت عنوان Thing
تعریف کردهایم که در حین ایجاد هر گونه آبجکتی از کلاس متد ()__init__
از کلاس مذکور به منظور مقداردهی اولیه به آن فراخوانی میشود که اولین آرگومان این متد self
است که اشاره به خود کلاس دارد و بیانگر این است که آبجکت ساختهشده متعلق به این کلاس خاص است و آرگومان دوم نیز بیانگر پارامتری است که قرار است تا به عنوان آرگومان ورودی برای هر آبجکت ساختهشده از این کلاس در نظر گرفته شود:
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
بنابراین متدی تحت عنوان ()__init__
برای این کلاس تعریف کرده و دو آرگومان self
و value
را به آن میدهیم که self
اشاره بر تعلق این متد به کلاس Thing
داشته و value
نیز بیانگر آرگومانی است که در هنگام ساخت آبجکت جدید از این کلاس باید مقداردهی شود.
دستور خط سوم بیانگر این موضوع است که اتربیوت value_
در تمامی آبجکتهای ساختهشده از کلاس Thing
باید به مقدار آرگومان value
از این کلاس اختصاص داده شوند. حال در خط چهارم قصد داریم تا عملکرد متد ()gt
را تغییر دهیم که برای این منظور فانکشن ()__gt__
از این کلاس را فراخوانی کرده و دو آرگومان ورودی self
و other
را به آن اختصاص میدهیم که آرگومان self
به منظور اشاره بر کلاسی تعریف شده که این متد متعلق به آن است و other
نیز به عنوان آرگومان ورودی به آبجکت ساختهشده از این کلاس اختصاص خواهد یافت که در ادامه و در خط پنجم گفتهایم که مقدار اولیۀ اختصاصیافته به آبجکت این کلاس را با مقدار تعریفشده برای آبجکت جدید از این کلاس مقایسه کند و در صورتی که مقدار اولیه بزرگتر از مقدار جدید بود، عبارت True
را در خروجی ریترن کند.
حال در خط ششم قصد داریم تا عملکرد متد ()lt
را تغییر دهیم که روال کار همانند توضیحات بیانشده در رابطه با متد ()gt
میباشد با این تفاوت که در خط هفتم گفتهایم که مقدار اولیۀ اختصاصیافته به آبجکت این کلاس را با مقدار جدید تعریفشده به آبجکت جدید از این کلاس مقایسه کند و در صورتی که مقدار اولیه کوچکتر از مقدار جدید بود، عبارت True
را ریترن کند.
در ادامه آبجکتی جدید از کلاس Thing
تحت عنوان something
میسازیم و مقدار ورودی 100 را به آن میدهیم و آبجکتی دیگر از این کلاس تحت عنوان nothing
ساخته و مقدار ورودی 10 را به آن میدهیم حال برای اینکه دستورهای مربوط به دو خط یازدهم و سیزدهم اجرا شوند (دو آبجکت مد نظر با هم مقایسه شوند)، مفسر پایتون چک میکند که آیا متدهای مربوط به عملگرهای مقایسه در داخل این کلاس تعریف شدهاند یا خیر و همانطور که میبینیم دو متد ()__lt__
و ()__gt__
در این کلاس تعریف شدهاند و از همین روی این متدها فراخوانی شده و از آنجایی که مقدار ورودی 100 بزرگتر از عدد 10 است، دستور خط یازدهم عبارت True
را ریترن میکند و بدین ترتیب نیز دستور خط سیزدهم عبارت False
را ریترن میکند.
اما در مورد خط پانزدهم باید گفت که هنگامی که مفسر پایتون به عملگر +
میرسد، چک میکند که آیا متد مربوط به این عملگر یا به عبارتی ()__add__
در کلاس Thing
تعریف شده است یا خیر و همانطور که در کد فوق میبینید، متدی تحت این عنوان در این کلاس تعریف نشده است و بنابراین اجرای دستور خط پانزدهم منجر به ارور خواهد شد.
pprint
این ماژول امکانی را برای دولوپرهای پایتون فراهم میآورد تا بتوانند برخی دیتا استراکچرهای پیچیده و یا تودرتو در قالب جیسون را به شکلی زیبا و خوانا در خروجی چاپ کنند. گرچه فانکشن ()print
نیز همین کار را انجام میدهد اما این در حالی است که فانکشن ()print
در مورد چاپ دادههای پیچیده از قابلیت خوانایی پایینی برخوردار است که در همین راستا مثال زیر را برای ماژول pprint
مورد بررسی قرار میدهیم:
import requests
import pprint
url = 'https://randomuser.me/api/?results=1'
users = requests.get(url).json()
pprint.pprint(users)
همانطور که در کد بالا میبینید، ابتدا ماژول requests
را در برنامه ایمپورت میکنیم که به منظور دریافت دیتای مربوط به یک یوآرال خاص در قالب جیسون به کار گرفته میشود و در ادامه ماژول pprint
را ایمپورت کرده و متغیری تحت عنوان url
را به منظور نگاهداری آدرس وبپیج مد نظر تعریف میکنیم. در ادامه آبجکتی تحت عنوان users
از کلاس ()get
مربوط به ماژول requests
ساختهایم تا دیتای مد نظر را از آدرس یوآرال مذکور و در قالب جیسون فِچ کرده و در آن نگاهداری کند که در ادامه این متغیر را به عنوان آرگومان ورودی به فانکشن ()pprint
از ماژول pprint
دادهایم تا دیتای مد نظر را به شکلی ساختاریافته در خروجی چاپ کند.
صَف
زبان پایتون قابلیت برنامهنویسی به صورت اصطلاحاً Multithreading (چندنَخی) را دارا است که در آن برخی از دستورالعملهای برنامه امکان اجرا به صورت Concurrent (موازی) را دارند که این قابلیت با بهکارگیری از ماژول استاندارد Queue
در این زبان تسهیل میشود.
این ماژول امکان ساخت دیتا استراکچرهایی از نوع صَف را برای دولوپرها فراهم میکند به طوری که قابلیت هندل کردن برخی از تَسکها بر اساس یکسری قوانین خاص برای ایشان فراهم میشود که یکی از این قوانین، First In First Out یا به اختصار FIFO است که در آن هر یک از تَسکها به همان ترتیبی که وارد صف شدهاند اجرا میشوند و قانون بعدی Last In First Out یا به اختصار LIFO است که بر اساس این قانون نیز اولین تَسک اضافهشده به صف در ابتدا اجرا میشود و در نهایت قانون دیگری وجود دارد که در آن دولوپرها برای هر یک از تَسکهای موجود در صف، اولویتهای متفاوتی را تعریف میکنند و تَسکی که از اولویت بالاتری برخوردار بوده در ابتدا بازیابی و اجرا میشود.
__repr__
این مورد هم یکی از فانکشنهای Built-in در زبان پایتون است که دولوپرها میتوانند فانکشن مذکور را برای نمایش یک توصیف رسمی از فیچرهای آبجکت مد نظر خود استفاده کنند. برای مثال در کُد زیر داریم:
file = open('test.txt', 'r')
print(file)
در کد بالا، آبجکتی تحت عنوان file
از فانکشن ()open
ساخته و دو آرگومان را به عنوان ورودی به این فانکشن پاس دادهایم که هر یک از این آرگومانها به ترتیب مربوط به نام فایلی است که به عنوان ورودی به فانکشن مذکور دادهایم و آرگومان دوم هم بیانگر سطح دسترسی ما به فایل مد نظر است که در اینجا کیوورد r
اشاره به کلمۀ Read دارد و بیانگر این موضوع است که سطح دسترسی ما به این فایل صرفاً «خواندن» فایل بوده و نمیتوانیم چیزی را از آن حذف و یا به آن اضافه کنیم.
در ادامه و در خط دوم از برنامه خواستهایم تا اطلاعات فایل مذکور که در متغیر file
ذخیره شده است را در خروجی چاپ کند که یک روال معمول برای نمایش اطلاعات فایل مد نظر است و در شرایطی که بخواهیم توصیفی به اصطلاح کاستومایزشده از این فایل در معرض دیدمان قرار گیرد، از فانکشن ()__repr__
استفاده میکنیم که برای این منظور داریم:
class someClass:
def __repr__(self):
return "<some description here>"
someInstance = someClass()
# prints <some description here>
print(someInstance)
همانطور که در کد فوق میبینید، فانکشن ()__repr__
متناسب با نیاز دولوپرها اورلود شده است که در همین راستا این متد را در کلاسی تحت عنوانِ دلخواهِ someClass
تعریف کرده و آرگومان self
به این متد داده شده است که اشاره به تعلق این متد به کلاس someClass
دارد و دستور خط سوم نیز بیانگر این موضوع است که متد مذکور توضیحی متناسب با نیاز دولوپر را در خروجی ریترن کند. در ادامه و در خط چهارم آبجکتی تحت عنوان someInstance
از کلاس مذکور ساختهایم و در خط پنجم این آبجکت را به فانکشن ()print
پاس دادهایم تا نتیجه را در خروجی چاپ کند.
sh
این لایبرری اینترفیسی را برای دولوپرها فراهم میآورد تا بتوانند پِراسسهای زیرشاخۀ برنامه را به صورت یکپارچه و تحت عنوان یک فانکشن معمولی فراخوانی کنند و به برخی از لایبرریهای متفاوت مورد نیاز برای اجرای هر یک از این پِراسسها دسترسی پیدا کرده و آنها را هندل کنند که برای مواردی همچون خودکارسازی وُرکفلوها و هندل کردن تَسکهای مختلف به صورت یکپارچه مفید است.
تایپ هینت
پایتون یک زبان برنامهنویسی به اصطلاح داینامیک تایپ است بدین معنی که برای تعریف نوع متغیرها، فانکشنها و کلاسها نیاز نیست که دیتا تایپ مربوط به هر یک از آنها را در برنامه مشخص کنیم که این فیچر منجر به افزایش سرعت توسعهٔ نرمافزار میشود اما این در حالی است که عدم تعریف دیتا تایپ در نوشتن کدها معایبی نیز دارا است که از جملهٔ مهمترین آنها میتوان به ارورهای ناشی از عدم تشخیص دیتا تایپ در پروژههای بزرگ و کاهش خوانایی کُد اشاره کرد که در همین راستا از نسخۀ 3.5 به بعدِ پایتون، قابلیتی تحت عنوان Type Hint به این زبان افزوده شد که امکان اشارۀ مستقیم به دیتا تایپ متغیرها و همچنین خروجی فانکشنهای برنامه را برای دولوپرها فراهم کرده است. برای مثال در کد زیر داریم:
def addTwo(x : int) -> int:
return x + 2
در کُد فوق فانکشنی تحت عنوان ()addTwo
تعریف کردهایم و پارامتر x
را به عنوان آرگومان ورودی به آن پاس دادهایم و پس از علامت :
گفتهایم که پارامتری ورودیِ x
باید از نوع int
(عدد صحیح) باشد و علامت <-
و پس از آن کلمۀ int
بدین معنا هستند که خروجی فانکشن مذکور نیز از جنس int
خواهد بود که در نهایت در خط دوم گفتهایم که عدد ورودی را با عدد 2 جمع کرده و در خروجی ریترن کند.
همچنین زبان پایتون فیچری تحت عنوان Type Aliase دارا است که در آن میتوان دیتا تایپ مد نظر خود را به یک متغیر فرضی منتسب کرد. در واقع، یک نام مستعار به دیتا تایپ مد نظر خود اختصاص میدهیم تا در صورت نیاز به ذکر آن در طِی برنامه، با ذکر این نام مستعار پیچیدگی کُد کاهش یافته و موجب خوانایی بیشتر آن میشود و برای این منظور زبان پایتون ماژولی تحت عنوان typing
دارا است:
import typing
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)
در توضیح کد فوق باید بگوییم که ابتدا ماژول typing
را ایمپورت کرده و در خط دوم نام مستعار Vector
را به دیتا تایپ «لیستی از اعداد اعشاری» اختصاص دادهایم و در خط سوم نیز گفتهایم که برای نوع دادۀ «لیستی از یکسری Vector
» که بیانکنندۀ لیستهای تودرتو از اعداد اعشاری بوده یا به عبارتی لیستی متشکل از چند سطر از اعداد اعشاری میباشد، نام مستعار Matrix
را انتخاب کردهایم.
در ادامه و در خط چهارم فانکشنی تحت عنوان addMatrix
را تعریف کردهایم و قصد داریم تا این فانکشن دو ماتریس فرضی a
و b
را با هم جمع کند که در همین راستا به فانکشن addMatrix
دو آرگومان ورودی a
و b
را دادهایم و دیتا تایپ هر دو را Matrix
تعیین کردهایم (Matrix
یک نام مستعار برای دیتا تایپ لیستی چند سطری از اعداد اعشاری میباشد) و گفتهایم که خروجی این فانکشن نیز از نوع Matrix
خواهد بود.
در خط پنجم متغیر result
را تعریف کردهایم که قرار است تا خروجی حاصل از جمع دو ماتریس را نگاهداری کند و در خط ششم دو متغیر تحت عنوان i
و row
را تعریف کردهایم که بتوانیم اِلِمانهای هر یک از سطرهای ماتریس مد نظر را پیمایش کنیم.
در ادامه تمامی سطرهای پیمایششده از ماتریس مذکور را در متغیری تحت عنوان result_row
ذخیره خواهیم کرد و کیورد enumerate
نیز به عنوان شمارندهای در جهت پیمایش تکتک اِلِمانهای هر سطر از این ماتریس به کار گرفته شده است. در خط هشتم دو متغیر j
و col
تعریف کردهایم تا بتوانیم هر یک از عناصر موجود در سطرهای ماتریس result_row
را پیمایش کنیم که به معنی پیمایش اِلِمانهای موجود در هر ستون از سطرهای ماتریس مذکور میباشد و در خط نهم نیز از برنامه خواستهایم تا اِلِمانهای متناظر از هر ستون و سطر مربوطه را با هم جمع کرده و در ماتریس result_row
نگاهداری کند که در نهایت مقادیر هر یک از سطرهای این ماتریس را با هم جمع کرده و نتیجه را در ماتریس result
ذخیره کردهایم.
برای فراخوانی این فانکشن نیز دو ماتریس تحت عناوین x
و y
تعریف کرده و به عنوان آرگومان ورودی به فانکشن مذکور میدهیم و همانطور که در خط آخر از کُد فوق میبینید، آبجکتی تحت عنوان z
از فانکشن ()addMatrix
ساخته و دو ماتریس x
و y
را به عنوان ورودی به این فانکشن دادهایم که نتیجۀ حاصل از جمع این دو ماتریس در متغیر z
نگاهداری خواهد شد.
uuid
UUID مخفف عبارت Universally Unique Identifier است و ماژولی تحت همین عنوان نیز در پایتون امکان تولید اعداد تصادفی منحصربهفرد به طول 128 بیت را در اختیار دولوپرها قرار میدهد به طوری که میتوان از این اعداد به عنوان یک شناسهٔ منحصربهفرد به منظور شناسایی داکیومنتها، هاستها، کلاینتهای مد نظر و هر آنچه که نیاز به نامگذاری یونیک دارند استفاده کرد. برای مثال در کد زیر داریم:
import uuid
user_id = uuid.uuid4()
print(user_id)
در کد فوق، ابتدا ماژول مربوطه را ایمپورت کرده و در ادامه با فراخوانی فانکشن ()uuid4
از این ماژول، عددی رندوم تولید خواهد شد که این عدد در متغیری تحت عنوان user_id
نگاهداری میشود که با اجرای دستور خط سوم عدد تصادفی مذکور توسط فانکشن ()print
چاپ میشود.
محیط مجازی
در زبان برنامهنویسی پایتون ممکن است برای توسعۀ اپلیکیشنها در برخی شرایط خاص نیاز به استفاده از پکیجها و یا ماژولهایی داشته باشیم که متعلق به نسخههای متفاوتی از این زبان باشند. برای مثال اپلیکیشن «الف» نیاز به یک ماژول خاص از پایتون نسخهٔ سه داشته اما این در حالی است که اپلیکیشن «ب» نیاز به همین ماژول از نسخۀ دوم این زبان دارد که در چنین شرایطی سولوشن مناسب برای حل این مشکل ساخت یک به اصطلاح Virtual Environment (محیط مجازی) است که با استفاده از آن بتوانیم نسخۀ دیگری از این زبان را نیز روی سیستم خود نصب کنیم که زبان برنامهنویسی پایتون برای ساخت و مدیریت این محیط روی سیستم، ماژولی تحت عنوان venv
دارا است که برای دانلود و نصب آن دستور زیر را در کامندلاین تایپ میکنیم:
$ python3 -m venv my-project
همانطور که در دستور فوق مشخص است، نسخۀ پایتون مد نظر خود را نوشته و در ادامه نام ماژول مورد نیاز برای ساخت محیط مجازی را آوردهایم و به دنبال آن نیز دایرکتوری مناسب برای ساخت این محیط را وارد میکنیم. درون این دایرکتوری یکسری دایرکتوریهای زیرشاخۀ دیگر به منظور نصب ماژولها و دیپندسیهای مورد نیاز اپلیکیشن ایجاد خواهند شد که بدین منظور هم ابتدا باید محیط مجازی ساختهشده را اَکتیو کنیم و در همین راستا دستور زیر را اجرا میکنیم:
$ source my-project/bin/activate
در نهایت داریم:
$ pip install all-the-modules
میتوانیم ماژولهای مد نظر خود را روی این محیط و با اجرای دستور فوق نصب کنیم.
wikipedia
وبسایت ویکیپدیا یکسری API دارا است که این امکان را در اختیار دولوپرها قرار میدهند تا بتوانند با دسترسی به آنها از دیتای عظیم وبسایت استفاده کنند و در همین راستا نیز زبان برنامهنویسی پایتون ماژولی تحت عنوان wikipedia
دارد که قابلیت دسترسی به این وب سرویس را در اختیار دولوپرها قرار میدهد. همچنین این ماژول قابلیت پشتیبانی از زبانهای مختلفی همچون انگلیسی، فارسی و غیره را دارا است و از جملۀ دیگر ویژگیهای این ماژول میتوان به توانایی تشخیص پیجها، تاپیکها و مطالبی با عناوین مشابه اشاره کرد. همانطور که در کد زیر میبینید:
import wikipedia
result = wikipedia.page('Persian Language')
print(result.summary)
for link in result.links:
print(link)
ابتدا ماژول wikipedia
را ایمپورت کرده و در خط دوم گفتهایم که اطلاعات مربوط به واژگان «Persian Language» را از وبسایت ویکیپدیا فِچ کرده و در متغیر result
ذخیره کند و در خط سوم دیتای جمعآوریشده توسط فانکشن ()print
چاپ میشود. در ادامه و در خط چهارم هم گفتهایم که به ازای تمامی لینکهای موجود در دیتای جمعآوریشده، لینکهایی را در خروجی چاپ کند که در عنوان آنها یکی از کلماتِ «Persian» و «Language» به کار رفته باشد.
xkcd
در داکیومنتهای مربوط به برخی ماژولهای استاندارد پایتون شاهد برخی طرحهای تصویری آمیخته به طنز هستیم که در همین راستا وبسایت xkcd (سایتی برای انتشار طرحهای تصویری طنزآمیز در رابطه با زبان، لطیفه و ریاضیات) بخشی از مطالب خود را به انتشار طرحهای به اصطلاح Comic در رابطه با زبان پایتون اختصاص داده است مضاف بر اینکه این زبان ماژولی تحت عنوان xkcd
دارا است که اینترفیسی را در اختیار دولوپرها قرار میدهد تا بتوانند به این وبسایت دسترسی داشته و دیتای مد نظر خود را در قالب جیسون از آن بازیابی کنند. همچنین با اجرای دستور زیر در کامندلاین نیز میتوان به وبپیج طرحهای تصویری مربوط به زبان برنامهنویسی پایتون دسترسی یافت:
import antigravity
نیاز به توضیح نیست که برای استفاده از فیچرهای ماژول xkcd
ابتدا باید آن را طبق روال مثالهای قبل دانلود و نصب نمایید.
YAML
YAML مخفف عبارت YAML Ain’t Markup Language بوده و یک استاندارد رایج برای تبدیل دادهها به فرمتی است که دیتای مد نظر قابلیت انتقال، ذخیره و بازسازی در بستر وب را داشته باشد. همچنین استاندارد YAML یکسری فیچر به منظور نمایش دیتا دارا است که منجر بدین گشته تا به عنوان یک به اصطلاح Superset یا «زیرشاخه» از استاندارد جیسون به شمار آید که از جملۀ این فیچرها میتوان به امکان ذخیرهسازی آبجکتهای پیچیدهتر به همراه اِلِمانهای تشکیلدهندۀ آن و نوشتن فایلهای کانفیگ اشاره کرد.
در همین راستا، ماژول PyYAML
امکان استفاده از فرمت دادۀ YAML را در زبان برنامهنویسی پایتون برای دولوپرها فراهم میآورد که این ماژول قابلیت ذخیرهسازی تمامی دیتاتایپها و آبجکتهای کلاسهای تعریفشده در برنامه را در اختیار ایشان قرار میدهد.
zip
فانکشن از پیش تعریفشدۀ ()zip
قابلیتی دارا است که طی آن مقادیری از آبجکتهای متعلق به دو لیست را دریافت کرده و آنها را به یک نوع دادۀ دیکشنری متشکل از مقادیر این دو آرایه تبدیل میکند. برای مثال در کد زیر داریم:
keys = ['a', 'b', 'c']
vals = [1, 2, 3]
zipped = dict(zip(keys, vals))
در خط اول آرایهای تحت عنوانِ دلخواهِ keys
را تعریف کرده و سه مقدار اِسترینگ را در آن ذخیره کردهایم و در خط دوم آرایۀ دیگری تحت عنوان vals
تعریف کرده و سه مقدار عددی را در آن نگاهداری کردهایم. حال در ادامه با استفاده از دستور خط سوم، یک دیکشنری تحت عنوان zipped
میسازیم که کلیدهای آن از آرایۀ keys
و مقادیر متناظر آنها را از آرایۀ vals
و دقیقاً بر اساس ترتیب مطرحشده در دو آرایه انتخاب میکنیم که نتیجۀ حاصل ذخیرهشده در متغیر zipped
را به فانکشن از پیش تعریفشدۀ ()dict
میدهیم تا خروجی را در قالب نوع دادۀ دیکشنری در معرض دید ما قرار دهد.
آنچه در این مقاله گفته شد، برخی از کاربردیترین قابلیتهای زبان برنامهنویسی پایتون بود که با آگاهی از آنها میتوان کدهای اثربخشتری نوشت. همچنین اگر علاقمند به دیگر مباحث مرتبط هستید، با دنبال کردن برچسب #پایتون میتوانید به لیستی از مقالات مربوطه دست یابید.