در زبان پایتون، لازم نیست از قبل مشخص کنید که یک متغیر قرار است چه نوعی از داده را نگه دارد. خودش به صورت خودکار، نوع داده (data type) را تشخیص میدهد.
هر چیزی که در پایتون با آن کار میکنیم (مثل عدد، متن یا لیست)، یک نوع خاص دارد. اگر با این نوعها آشنا باشیم، راحتتر میتوانیم برنامه بنویسیم.
در این مقاله، با مهمترین انواع داده در پایتون ۳ آشنا میشوید. یاد میگیرید کدام نوعها قابل تغییرند، یعنی میشود بعداً مقدارشان را عوض کرد، و برای هر کدام مثال سادهای هم میبینید. در پایان هم با روشی آشنا میشوید که در نسخههای جدید پایتون میتوان نوع داده را به صورت دقیق مشخص کرد، مثل کاری که در زبانهایی مثل C یا جاوا انجام میشود.
نوع اعداد (Numbers) در پایتون
یکی از دستههای اصلی انواع داده در پایتون انواع عددی است. سه نوع عددی اصلی در پایتون ۳ وجود دارد: اعداد صحیح (int) برای اعداد بدون جزء اعشاری، اعداد اعشاری (float) برای اعداد ممیز شناور (دارای جزء اعشاری) و اعداد مختلط (complex) برای اعداد مرکب مختلط (دارای قسمت حقیقی و موهومی). نوع بولین (Bool) نیز زیرمجموعهای از اعداد صحیح است، زیرا مقادیر True و False در حافظه به صورت ۱ و ۰ عمل میکنند (هرچند برای خوانایی بهتر توصیه میشود از True/False به جای اعداد استفاده شود).
ویژگی مهم انواع عددی در پایتون این است که همهی آنها غیرقابلتغییر (immutable) هستند؛ یعنی اگر متغیری به مقدار ۵ تخصیص یافته باشد، تغییر مستقیم آن مقدار ممکن نیست بلکه باید شیء جدیدی ایجاد شود. در ادامه به هر یک از انواع عددی نگاهی میاندازیم:
عدد صحیح (int)
برای نمایش اعداد صحیح (مثبت، منفی یا صفر) استفاده میشود. در پایتون ۳ محدودهی اندازهی عدد صحیح نامحدود است و تنها به حافظهی موجود بستگی دارد. مثلا: x = 42 یک متغیر از نوع int با مقدار ۴۲ ایجاد میکند. عملیات ریاضی معمول (جمع، تفریق، …) روی اعداد صحیح قابل انجام است.
عدد اعشاری (float)
برای نمایش اعداد حقیقی دارای بخش اعشاری (ممیز شناور) به کار میرود. برای مثال y = 3.14 متغیری از نوع float میسازد. دقت اعداد اعشاری مبتنی بر پیادهسازی double در زبان C است و میتواند تا حدود ۱۵ رقم معنادار را نمایش دهد. اعداد علمی را نیز میتوان با این نوع نشان داد (مثلا 1.2e3 که برابر ۱۲۰۰ است).
عدد مختلط (complex)
نوعی داده برای نمایش اعداد مختلط با قسمت حقیقی و موهومی است. یک عدد مختلط در پایتون به صورت a + bj نوشته میشود؛ مثلا z = 2+3j مقداری از نوع complex است که قسمت حقیقی آن ۲ و قسمت موهومی آن ۳ میباشد. قسمتهای حقیقی و موهومی یک متغیر complex را میتوان با ویژگیهای z.real و z.imag دستیابی کرد.
مثال: در کد زیر انواع عددی مختلف در پایتون استفاده شده است:
x = 7 # int – عدد صحیح
y = 2.5 # float – عدد اعشاری
z = 1 + 2j # complex – عدد مختلط
print(type(x), type(y), type(z))
خروجی: <class ‘int’> <class ‘float’> <class ‘complex’> که نوع هر متغیر را تأیید میکند.
نوع بولین (Boolean) در پایتون
دیتا تایپ بولین برای بیان مقادیر منطقی به کار میرود و دقیقا دو مقدار ثابت دارد: True (درست) و False (نادرست). این نوع داده در تصمیمگیریهای منطقی و شروط (if و while) استفاده میشود. بولینها در پایتون در واقع زیر مجموعهای از اعداد صحیح هستند؛ یعنی True معادل عدد ۱ و False معادل ۰ است، اما استفادهی مستقیم از این اعداد به جای بولین توصیه نمیشود چون خوانایی کد را کاهش میدهد.
مثال:
is_valid = True
print(is_valid) # خروجی: True
print(is_valid + 1) # خروجی: 2 (چون True معادل 1 است)
در مثال بالا، متغیر is_valid از نوع bool مقدار True دارد. همچنین مشاهده میکنید که True + 1 نتیجه ۲ داده است، زیرا در باطن True برابر ۱ در نظر گرفته میشود. (در عمل بهتر است برای جمع زدن، ابتدا مقدار بولین را به int تبدیل کنید یا از این ویژگی صرفنظر کنید).
نوع رشته (String) در پایتون
نوع دادهی متنی در پایتون با کلاس str نمایش داده میشود که برای نگهداری رشتههای متنی (دنبالهای از کاراکترها) به کار میرود. رشتهها در پایتون دنبالههایی از کاراکترهای یونیکد هستند، به این معنا که پس از ایجاد یک رشته نمیتوان کاراکترهای آن را تغییر داد (باید رشتهی جدیدی ساخت). تعریف رشته میتواند با استفاده از علامت نقلقول انجام شود:
- با نقلقول تک یا جفت: مثلا ‘Hello‘ یا “Hello“ هر دو رشتهی Hello را میسازند.
- با نقلقول سهتایی برای رشتههای چندخطی: مثلا “””Line1\nLine2″”” که اجازه میدهد رشته در چند خط نوشته شود.
همچنین پیشوند f برای قالببندی رشته (از پایتون ۳٫۶ به بعد) قابل استفاده است که به شما اجازه میدهد متغیرها را مستقیما داخل رشته قرار دهید. به عنوان مثال:
name = "Ali"
msg = f"Hello, {name}!"
print(msg) # خروجی: Hello, Ali!
در این مثال یک رشته با f (فرمت) ساخته شده است. رشتهها چون immutable(غیر قابل تغییر) هستند، عملیات روی رشته (مثل الحاق کردن دو رشته با +) رشتهی جدیدی برمیگرداند و شیء اصلی تغییر نمیکند.
مثال:
text = "Python"
print(text[0]) # خروجی: P
text = text + "3"
print(text) # خروجی: Python3
متغیر text ابتدا حاوی “Python” بود. با text[0] اولین کاراکتر آن (P) را دریافت کردیم.
در خط بعد با “text + “3 رشتهی جدید “Python3” ساخته شده و دوباره به text نسبت داده شد.
نوع لیست (Lists) در پایتون
لیست با نوع list، یک نوع داده ترتیبی برای نگهداری مجموعهای مرتّب از عناصر است. لیست در پایتون معادل آرایه در برخی زبانها است با این تفاوت که میتواند انواع داده مختلف را در خود جای دهد. لیستها با کروشه ([ ]) تعریف میشوند. برخلاف رشته و تاپل، لیستها قابلتغییر (mutable) هستند یعنی پس از ایجاد میتوان عناصرشان را اضافه، حذف یا تغییر داد. به دلیل mutable بودن، لیست یک نوع غیرقابل هش محسوب میشود و نمیتوان از آن به عنوان کلید دیکشنری یا عضو یک مجموعهی (set) دیگر استفاده کرد.
مثال:
fruits = ["Apple", "Banana", "Cherry"]
print(fruits[1]) # خروجی: Banana
fruits.append("Orange")
print(fruits) # خروجی: ['Apple', 'Banana', 'Cherry', 'Orange']
fruits[0] = "Grape"
print(fruits) # خروجی: ['Grape', 'Banana', 'Cherry', 'Orange']
در این مثال یک لیست حاوی نام میوهها ایجاد شده است. ابتدا عنصر با ایندکس ۱ (“Banana”) چاپ میشود. سپس با متد append مقدار “Orange” به لیست اضافه شده و در نهایت عنصر اول لیست از “Apple” به “Grape” تغییر داده شده است. تمام این عملیات به دلیل mutable بودن لیست امکانپذیر است.
نوع تاپل (Tuple) در پایتون
تاپل در پایتون نوع دادهی ترتیبی دیگری شبیه به لیست است با این تفاوت که غیرقابلتغییر (immutable) میباشد. تاپلها معمولا با پرانتز ( ) تعریف میشوند. هنگامی که نمیخواهید ترتیب عناصر تغییر کند یا به صورت ناخواسته دچار تغییر شود، میتوانید از تاپل استفاده کنید. به علت immutable بودن، از تاپل میتوان به عنوان کلید در دیکشنری یا عضو مجموعه استفاده کرد (البته مشروط بر اینکه عناصر داخل تاپل هم hashable باشند).
colors = ("red", "green", "blue")
print(colors[2]) # خروجی: blue
#مثال مشابه
# colors.append("yellow") (خطا! تاپل متدی برای افزودن ندارد)
# colors[0] = "black" (خطا! عناصر یک تاپل غیرقابل تغییرند)
در این مثال یک تاپل حاوی آیتمهایی از جنس string با رنگ های red , green , blue است. با colors[2] مقدار عنصر سوم (“blue”) گرفته میشود. تلاش برای افزودن عنصر جدید یا تغییر عنصر موجود با خطا مواجه میشود زیرا تاپل پس از ایجاد شدن تغییرپذیر نیست.
نوع مجموعه(Set) در پایتون
مجموعه با نوع set در پایتون برای نگهداری مجموعهای از اقلام منحصربهفرد (بدون تکرار) به کار میرود. مجموعهها بدون ترتیب هستند، به این معنی که ترتیب اضافه شدن عناصر در خروجی لحاظ نمیشود. مجموعه با براکتهای {…} یا تابع set() تعریف میشود. عناصر یک مجموعه باید قابل هش (hashable) باشند، بنابراین نوعهای mutable مانند لیست قابل عضو شدن در مجموعه نیستند. نوع دیگری به نام frozenset نیز وجود دارد که معادل مجموعهی غیرقابلتغییر است.
در پایتون دو نوع مجموعهی built-in وجود دارد: set (قابلتغییر) و frozenset (غیرقابلتغییر). مجموعهی معمولی (set) mutable است یعنی میتوان پس از ایجاد، با متدهایی مانند add و remove به آن عضو اضافه یا از آن حذف کرد. در مقابل، frozenset پس از ایجاد شدن ثابت است و به همین دلیل قابل هش میباشد (میتواند به عنوان کلید دیکشنری یا عضو مجموعهی دیگر استفاده شود).
مثال:
A = {1, 2, 3, 3}
B = {3, 4, 5}
print(A) # خروجی: {1, 2, 3}
A.add(4)
print(A) # خروجی: {1, 2, 3, 4}
print(A & B) # خروجی: {3, 4} (اشتراک A و B)
C = frozenset([10, 20, 30])
# C.add(40) # خطا! frozenset قابل تغییر نیست
در این مثال، مجموعهی A ایجاد شده که مقادیر تکراری را حذف میکند (دو عدد ۳ یکی شده است). سپس مقدار ۴ به A افزوده شده است. عملگر & برای گرفتن اشتراک دو مجموعه استفاده شده که نتیجه {3, 4} است. در انتها یک frozenset ساخته شده که تلاش برای تغییر آن با خطا مواجه میشود.
نوع دیکشنری (Dictionary) در پایتون
دیکشنری با نوع dict در پایتون یک نوع دادهی نگاشتی (Mapping) است که مجموعهای از زوجهای کلید و مقدار را نگهداری میکند. هر کلید به یک مقدار مرتبط است، شبیه به یک دفترچه تلفن که یک اسم (کلید) به شماره آن اسم (مقدار) نگاشت شده است. دیکشنری در پایتون با آکولاد { } و به صورت جفتهای key:value تعریف میشود. مثلا: person = {“name”: “Ali”, “age”: 30} یک دیکشنری با دو ورودی (کلید name و مقدار “Ali”, کلید age و مقدار 30) میسازد.
دیکشنری تنها نوع نگاشتی استاندارد در پایتون است و قابلتغییر (mutable) میباشد؛ یعنی میتوان پس از ایجاد، زوجهای جدید اضافه کرد، یا کلیدهای موجود را حذف/ویرایش کرد. کلیدهای دیکشنری باید غیر قابل تغییر باشند (نوعهایی مثل رشته، عدد، تاپلهای تغییرناپذیر) و تکراری نباشند، ولی مقادیر میتوانند قابل تغییر یا تکراری باشند.
از نسخهی پایتون ۳٫۷ به بعد، ترتیب درج عناصر در دیکشنری حفظ میشود، بنابراین اگرچه دیکشنری ذاتا ساختاری مرتبشده بر اساس مقدار کلیدها نیست، میتوانید مطمئن باشید که هنگام پیمایش دیکشنری (مثلا با for یا متد ()items)، کلیدها به ترتیبی که اضافه شدهاند برگردانده میشوند.
مثال:
student = {"id": 101, "name": "Sara"}
print(student["name"]) # خروجی: Sara
student["age"] = 20
print(student) # خروجی: {'id': 101, 'name': 'Sara', 'age': 20}
del student["id"]
print(student) # خروجی: {'name': 'Sara', 'age': 20}
در این مثال، دیکشنری اولیه شامل شناسه و نام دانشجو است. با student[“name”] مقدار مرتبط با کلید “name” دریافت میشود. سپس یک زوج جدید با کلید “age” اضافه شده است. در نهایت کلید “id” و مقدار مرتبط با آن از دیکشنری حذف شده است. تمامی این عملیات به دلیل mutable بودن دیکشنری ممکن است.
مقدار تهی (None)
پایتون دارای یک مقدار خاص به نام None (از نوع NoneType) برای نشان دادن «هیچ مقدار» یا تهی بودن است. None معادل Null در زبانهای دیگر است. معمولا از None برای مقادیر پیشفرض که هنوز مقداردهی نشدهاند یا بازگشت تابعی که چیزی برنمیگرداند استفاده میشود. فقط یک شیء از نوع NoneType وجود دارد که همان None است و این نوع immutable بوده و بیشتر برای بررسی منطقی به کار میرود (مثلا مقایسه میکنیم که یک متغیر is None هست یا خیر). به عنوان مثال، نتیجهی تابع print() در پایتون None است، زیرا مقداری برنمیگرداند. در شرطهای بولین، None مانند False عمل میکند.
مثال:
value = None
if value is None:
print("No value") # این چاپ میشود چون value تهی است
در این قطعه کد، متغیر value به مقدار تهی None اشاره میکند و بنابراین شرط is None برقرار است.
نوعدهی پویا در برابر نوعدهی ایستا در پایتون
همانطور که در ابتدا اشاره شد، پایتون یک زبان با نوعدهی پویا است؛ یعنی نوع متغیرها در زمان اجرا و بر اساس مقدارشان تعیین میشود. این ویژگی انعطافپذیری بالایی به برنامهنویس میدهد تا متغیر واحدی را در زمانهای مختلف به مقادیر با انواع گوناگون اختصاص دهد. برای مثال هیچ مشکلی ندارد که ابتدا یک متغیر را برابر عدد ۱۰ قرار دهیم و سپس در جای دیگر همان متغیر را برابر یک رشته قرار دهیم – مفسر پایتون نوع جدید را در لحظه تشخیص میدهد. از سوی دیگر، زبانهایی مثل C یا جاوا نوعدهی ایستا دارند، بدین صورت که باید نوع متغیر را صراحتا اعلام کنید و مثلا یک متغیر نوع int نمیتواند در میانهی برنامه به یک رشته تغییر یابد.
پایتون در عین پویا بودن، یک زبان strongly-typed نیز محسوب میشود، به این معنی که انواع با هم به سادگی قابل تبدیل ضمنی نیستند. مثلا تلاش برای جمع یک عدد و رشته به خطای نوع (TypeError) منجر میشود و پایتون به صورت خودکار آنها را به نوع مشترک تبدیل نمیکند.
مثال:
x = 10 # x type is int
x = "Hello" # x type is str
y = 5 + "5" # خطا: نمیتوان عدد را با رشته جمع کرد
در این مثال ابتدا x یک عدد صحیح بود و سپس به یک رشته تغییر داده شد که از نظر پایتون مجاز است. اما جمع کردن عدد 5 با رشته “5” غیرمجاز است و خطا تولید میکند، زیرا عملیات تعریفشدهای برای جمع int و str وجود ندارد.
Static types یا Type Hints در پایتون
اگرچه پایتون همیشه یک زبان داینامیک تایپ بوده است، اما از نسخهی ۳٫۵ قابلیتی به نام نوعنمایی یا Type Hints معرفی شد که به برنامهنویسان امکان میدهد نوع متغیرها و پارامترهای توابع را به صورت اختیاری مشخص کنند. این type hintها در زمان اجرای برنامه اجباری نیستند (پایتون آنها را بررسی نمیکند و همچنان اجازه میدهد مقادیر ناسازگار را قرار دهید!)، اما ابزارهای بررسی استاتیک مانند mypy یا IDE میتوانند از این اطلاعات برای کشف خطاهای احتمالی و اشتباهات برنامه نویسی استفاده کنند. به عبارت دیگر، Type Hints مزایای static type (مثل پیدا کردن ناسازگاریهای type ها قبل از اجرا) را تا حدی به دنیای پایتون میآورد، بدون آنکه ماهیت پویا بودن زبان را تغییر دهد(کی بهتر از تو که بهترینی 🙂 .)
برای مثال، میتوان نوشت:
def add_numbers(x: int, y: int) -> int:
return x + y
در اینجا anotation نوع برای تابع add_numbers مشخص کردهایم که x و y باید int باشند و خروجی تابع نیز int است. این صرفا یک راهنمایی است و اگر تابع را با مقادیر غیر int صدا بزنیم، پایتون در زمان اجرا خطایی صرفا بابت type hint نخواهد داد؛ اما یک ابزار بررسی استاتیک تایپها میتواند در زمان توسعه به ما هشدار دهد.
یکی از ویژگیهای جدید از پایتون ۳٫۱۰ معرفی عملگر Union Type برای Type Hints است. با این قابلیت میتوان به جای استفاده از typing.Union به شکل مختصرتر از علامت | استفاده کرد تا چند نوع مجاز برای یک متغیر یا پارامتر را مشخص کنیم. برای مثال، در نسخههای قدیمیتر مینوشتیم Union[int, str] اما در پایتون ۳٫۱۰ به بعد میتوانیم بنویسیم int | str. به طور مشابه این علامت را میتوان در تابع isinstance نیز به کار برد (مثلا isinstance(x, int | str)) که خوانایی کد را بالاتر میبرد.
جدول مقایسه انواع دادههای پایتون
در جدول زیر، یک جمعبندی از انواع دادهی پرکاربرد پایتون ۳، قابلتغییر بودن آنها و یک مثال برای هر نوع آمده است:
| نوع داده | قابلتغییر؟ (mutable / immutable) | مثال |
|---|---|---|
| عدد صحیح (int) | خیر (immutable) | x = 42 |
| عدد اعشاری (float) | خیر (immutable) | x = 3.14 |
| عدد مختلط (complex) | خیر (immutable) | x = 2+3j |
| بولین (bool) | خیر (immutable) | x = True |
| رشته (str) | خیر (immutable) | s = "Hello" |
| لیست (list) | بله (mutable) | lst = [1, 2, 3] |
| تاپل (tuple) | خیر (immutable) | t = (1, 2, 3) |
| مجموعه (set) | بله (mutable) | A = {1, 2, 3} |
| مجموعه ثابت (frozenset) | خیر (immutable) | B = frozenset({1, 2, 3}) |
| دیکشنری (dict) | بله (mutable) | d = {"a": 1, "b": 2} |
| بایتها (bytes) | خیر (immutable) | b = b"Hi" |
| آرایهی بایت (bytearray) | بله (mutable) | ba = bytearray(b"Hi") |
| تهی (NoneType) | خیر (immutable) | x = None |
در این جدول، قابلتغییر به این معناست که پس از ایجاد شیء میتوان محتویات یا حالت آن را تغییر داد. همانطور که دیده میشود، انواع عددی، رشته، تاپل،frozenset ، bytes و None همگی تغییرناپذیرند، در حالی که لیست، دیکشنری، set و bytearray قابل تغییرند. دانستن این ویژگی مهم است زیرا بر نحوهی استفاده از این انواع (مثلا به عنوان کلید دیکشنری یا عضو مجموعه) تاثیر میگذارد. همچنین نوع بولین را میتوان زیرمجموعهای از int در نظر گرفت، اگرچه در جدول به صورت جداگانه فهرست شده است.
منبع : w3school python.org realpython