درس ۰۷: انواع آماده شی - بخش یکم

پایتون هر «نوع داده» (Data Type) را توسط یک کلاس ارایه می‌دهد؛ بنابراین هر داده یک نمونه یا یک شی از کلاسی مشخص است. هر چند برنامه‌نویس نیز می‌تواند با تعریف کلاس، نوع دلخواه خود را داشته باشد ولی در این درس می‌خواهیم درباره آن بخشی از انواع داده یا انواع شی‌ای که به شکل آماده (Built-in) در اختیار مفسر زبان پایتون قرار داده شده است صحبت کنیم.

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

سطح: مقدماتی



انواع عددی

در زبان پایتون دسته‌ای از انواع شی وجود دارد که برای کار با داده‌های عددی ایجاد گشته‌اند؛ از این جهت به عنوان «انواع عددی» (Numeric Types) شناخته می‌شوند. این انواع شی عبارتند از:

  • صحیح (Integer)
  • ممیز شناور (Floating-Point)
  • مختلط (Complex)
  • دسیمال (Decimal)
  • کسر (Fraction)
  • بولی (Boolean)

در ادامه به بررسی هر یک خواهیم پرداخت.

صحیح

این نوع از اشیا تمام اعداد مثبت و منفی بدون «ممیز اعشار» را شامل می‌شوند؛ مانند: 1234، 26- و...

ارایه نوع عدد صحیح از موارد اختلاف در نسخه‌های 2x و 3x می‌باشد.

در نسخه‌های 2x اعداد صحیح در قالب دو نوع int (با محدودیت اندازه) و long (بدون محدودیت اندازه) بیان می‌شوند:

>>> a = 3           # Python 2.x
>>> type(a)
<type 'int'>

>>> b = 3L
>>> type(b)
<type 'long'>

به این صورت که اگر عدد صحیحی با حرف L (اِل بزرگ) یا l (اِل کوچک) پایان یابد؛ به صورت نوع long در نظر گرفته خواهد شد. البته توجه داشته باشید چنانچه در نوع int سرریز (Overflow) رخ دهد؛ خطایی به وجود نخواهد آمد و پایتون به صورت خودکار شی نوع int را به شی‌ای از نوع long تبدیل (Convert) خواهد کرد.

بیشینه و کمینه مقدار یک شی از نوع int به ترتیب با استفاده از sys.maxint و sys.maxint - 1 - قابل دریافت است که می‌توانید این مقادیر را در یک نمونه کامپیوتر با معماری ۶۴ بیتی به صورت پایین مشاهده نمایید:

>>> import sys            # Python 2.x

>>> sys.maxint
9223372036854775807
>>> type(_)               # _ is result of the last executed statement  => 9223372036854775807
<type 'int'>

>>> - sys.maxint - 1
-9223372036854775808

>>> type(sys.maxint + 1)
<type 'long'>

در نسخه‌های 3x اعداد صحیح تنها در قالب یک نوع int (بدون محدودیت اندازه) ارایه می‌گردد و باید توجه داشت که استفاده از حرف L (یا l) در پایان اعداد صحیح مجاز نمی‌باشد:

>>> a = 3                   # Python 3.x
>>> type(a)
<class 'int'>

>>> b = 3L
  File "<stdin>", line 1
    b = 3L
         ^
SyntaxError: invalid syntax
>>>

در این نسخه‌ها sys.maxint حذف شده است ولی می‌توان به جای آن از sys.maxsize استفاده کرد که مقدار آن در نمونه کامپیوتر پیش برابر پایین است:

>>> import sys              # Python 3.x

>>> sys.maxsize
9223372036854775807
>>> type(_)
<class 'int'>

>>> type(sys.maxsize + 1)
<class 'int'>

توجه

منظور از اندازه نامحدود اعداد این است که اندازه این اشیا تنها محدود به میزان حافظه‌ (Memory) آزاد بوده و تا هر اندازه‌ای که حافظه در دسترس باشد می‌توانند در محاسبات رشد داشته باشند.

در هر دو شاخه از پایتون؛ اعداد صحیح را می‌توان علاوه بر پایه ده؛ در پایه دو (Binary)، پایه هشت (Octal) و پایه شانزده (Hexadecimal) نیز در نظر گرفت. به این صورت که:

  • اعداد پایه دو می‌بایست با یک 0b یا 0B (صفر و حرف بی کوچک یا بزرگ) آغاز گردند؛ مانند: 0b11 که برابر عدد 3 در پایه ده است:

    >>> a = 0b11
    >>> type(a)
    <class 'int'>
    >>> a
    3
    
  • اعداد پایه هشت می‌بایست با یک 0o یا 0O (صفر و حرف اُ کوچک یا بزرگ) آغاز گردند؛ مانند: 0o14 که برابر عدد 12 در پایه ده است:

    >>> a = 0o14
    >>> type(a)
    <class 'int'>
    >>> a
    12
    

    همچنین در نسخه‌های 2x برای مشخص کردن عددی در این پایه می‌توان به جای 0o یا 0O، تنها از یک صفر 0 استفاده کرد:

    >>> 0o14    # Python 3.x and Python 2.x
    12
    
    >>> 014     # Python 2.x
    12
    
  • اعداد پایه شانزده می‌بایست با یک 0x یا 0X (صفر و حرف اِکس کوچک یا بزرگ) آغاز گردند؛ مانند: 0xA5 که برابر عدد 165 در پایه ده است:

    >>> a = 0xA5
    >>> type(a)
    <class 'int'>
    >>> a
    165
    >>> print(a)
    165
    

همانطور که در نمونه کدهای بالا نیز قابل مشاهده است؛ نوع شی صحیح در پایه‌های گوناگون تفاوتی نمی‌کند (همان int است) و در پایتون تنها از یک سینتکس متفاوت برای مشخص کردن آن‌ها استفاده شده است. همچنین علاوه بر وارد کردن این اشیا در حالت تعاملی؛ تابع (یا دستور) print نیز این اشیا را به پایه ده تبدیل کرده و سپس چاپ می‌‌کند.

برای تبدیل یک عدد صحیح در پایه ده به هر یک از این پایه‌ها می‌توانید از تابع‌های آماده ()bin [اسناد پایتون] برای تبدیل به پایه دو، ()oct [اسناد پایتون] برای تبدیل به پایه هشت و ()hex [اسناد پایتون] برای تبدیل به پایه شانزده استفاده نمایید. تنها توجه داشته باشید که خروجی هر یک از این تابع‌ها به صورت یک شی از نوع رشته یا String برگردانده می‌شود و نه یک نوع عددی:

>>> a = 3
>>> b = bin(a)
>>> b
'0b11'
>>> type(b)
<class 'str'>

>>> a = 12
>>> b = oct(a)
>>> b
'0o14'
>>> type(b)
<class 'str'>

>>> a = 165
>>> b = hex(a)
>>> b
'0xa5'
>>> type(b)
<class 'str'>

و برای برگرداندن پایه اعداد صحیح به پایه ده می‌توان از کلاس ()int [اسناد پایتون] استفاده کرد. آرگومان‌های نمونه این کلاس به صورت (int(str, base می‌باشد؛ آرگومان یکم: str می‌بایست یک «رشته عددی» یعنی یک عدد صحیح (در هر پایه‌ای) داخل نمادهای نقل قول (Quotation) باشد که آرگومان دوم، پایه (Base) آن را مشخص می‌کند. در نهایت این کلاس یک شی int متناظر با آرگومان یکم ولی در پایه ده را برمی‌گرداند:

>>> a = 165

>>> type(a)
<class 'int'>

>>> b = hex(a)          # Converted to hexadecimal
>>> b
'0xa5'

>>> type(b)
<class 'str'>

>>> int(b, 16)           # str='0xa5' base=16
165

>>> type(int(b, 16))
<class 'int'>

توجه داشته باشید که می‌توان اعداد را بدون حرف مشخص کننده پایه (0x 0o 0b) به این کلاس ارسال کنیم. همچنین از این کلاس می‌توان برای تبدیل نوع رشته‌های عددی در پایه ده به عدد صحیح استفاده کرد. مقدار پیش‌فرض آرگومان پایه 10 است؛ بنابراین در هنگام ارسال اعداد در این پایه، نیازی به ذکر پایه 10 نمی‌باشد:

>>> int("A5", 16)    # 0xA5
165
>>> a = "56"
>>> int(a, 10)
56
>>> int(a)
56
>>> int()
0

()int بدون آرگومان یک شی صفر از نوع صحیح را برمی‌گرداند.

توجه

منظور از «رشته عددی»، رشته‌ای است که به گونه‌ای بتوان آن را به یک عدد ارزیابی نمود. مانند: "25"، "0x2F" و... که بدیهی است قرار دادن رشته‌هایی همچون "0w55" و... - که به هیچ شکلی نمی‌توان آن‌ها را به عددی در پایتون ارزیابی نمود - در آرگومان ()int موجب بروز خطا می‌گردد.

با تفاوت شیوه ارایه نوع اعداد صحیح در بین نسخه‌های 2x و 3x پایتون آشنا شده‌ایم. فقط باید توجه داشت که در نسخه‌های 2x پایتون؛ کلاس ()int [اسناد پایتون] یک شی از نوع int را برمی‌گرداند و برای ایجاد اشیایی از نوع long کلاس مشابه دیگری با نام ()long [اسناد پایتون] در دسترس است:

>>> a = 25     # Python 2.x

>>> int(a)
25

>>> long(a)
25L

در هر دو شاخه از پایتون؛ اعداد در پایه ده را می‌توان با نوع عددی - نه به شکل رشته عددی - نیز به تابع ()int (یا ()long) ارسال نمود.

برای به دست آوردن اندازه یا میزان حافظه گرفته شده توسط یک شی به واحد بایت (Byte) می‌توان از تابع ()getsizeof [اسناد پایتون] درون ماژول sys استفاده نماییم - خروجی این تابع برای دو شی صحیح دلخواه در یک نمونه کامپیوتر ۶۴ بیتی به صورت پایین است:

>>> import sys                # Python 3.x
>>> a = 1
>>> sys.getsizeof(a)
28
>>> sys.getsizeof(10**100)
72
>>> import sys                # Python 2.x
>>> a = 1
>>> sys.getsizeof(a)
24
>>> sys.getsizeof(10**100)
72

ممیز شناور

تمام اعداد مثبت و منفی که شامل یک «ممیز اعشار» هستند در پایتون به صورت اشیایی با نوع float (معادل نوع double در زبان C) ارایه می‌شوند؛ مانند: 3.1415، .5 (برابر 5.0) و...

>>> a = 3.1415
>>> type(a)
<class 'float'>

>>> import sys
>>> sys.getsizeof(a)
24

جزییات این نوع با استفاده از sys.float_info [اسناد پایتون] قابل مشاهده است:

>>> import sys
>>> sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)

گاهی برای نمایش اعداد از شیوه «نماد علمی» (Scientific Notation) استفاده می‌شود؛ در پایتون هم می‌توان از حرف E یا e که معادل «ضرب در ۱۰ به توانِ» می‌باشد، برای این منظور استفاده کرد.

برای نمونه: عبارت 4 × 105، به شکل 4E5 یا 4e5 بیان می‌شود. پایتون این نوع اعداد را نیز در قالب اعداد ممیز شناور (اشیایی از نوع float) ارايه می‌دهد:
>>> 3e2
300.0

>>> type(3e2)
<class 'float'>

>>> 3e-2
0.03

>>> 3e+2
300.0

می‌توان از کلاس ()float [اسناد پایتون] برای تبدیل اعداد یا رشته‌های عددی به یک شی ممیز شناور استفاده کرد:

>>> a = 920

>>> type(a)
<class 'int'>

>>> float(a)
920.0

>>> type(float(a))
<class 'float'>

>>> float("920")
920.0

>>> float("3e+2")
300.0
>>> float()
0.0

()float بدون آرگومان یک شی صفر از نوع ممیز شناور را برمی‌گرداند.

چنانچه عددی از نوع ممیز شناور در آرگومان کلاس ()int قرار بگیرد؛ تنها بخش صحیح عدد برگردانده می‌شود:

>>> a = 2.31
>>> type(a)
<class 'float'>

>>> int(a)
2
>>> type(int(a))
<class 'int'>

>>> int(3.9)
3

با استفاده از کلاس ()float می‌توانیم اشیایی با مقدارهای مثبت و منفی «بی‌نهایت» (infinity) برابر: inf یا infinity و «تعریف نشده» (Not a Number) برابر: NaN ایجاد نماییم - چگونگی کوچک یا بزرگ نوشتن حروف این کلمه‌ها تفاوتی در آن‌ها ایجاد نمی‌کند:

>>> a = float('infinity')
>>> a = float('inf')
>>> a
inf

>>> b = float('-infinity')
>>> b = float('-inf')
>>> b
-inf

>>> c = float('NaN')
>>> c
nan
>>> a = float('inf')

>>> 5 / a
0.0

>>> a / a
nan
>>> a = float('inf')
>>> b = float('inf')
>>> a == b
True

>>> a = float('nan')
>>> b = float('nan')
>>> a == b
False

دو شی NaN با یکدیگر برابر نیستند.

برای بررسی اینکه مقدار یک شی «بی‌نهایت» یا «تعریف نشده» است؛ می‌توان به ترتیب از تابع‌های ()isinf [اسناد پایتون] و ()isnan [اسناد پایتون] درون ماژول math استفاده نماییم:

>>> a = float('inf')
>>> b = float('nan')

>>> import math

>>> math.isinf(a)
True
>>> math.isnan(b)
True

مختلط

همانطور که می‌دانیم اعداد مختلط (Complex Numbers) از یک بخش حقیقی (Real) و یک بخش موهومی (Imaginary) تشکیل شده‌اند. این اعداد در پایتون الگویی برابر RealPart + ImaginaryPart j دارند که حرف j نشانگر «واحد موهومی» است. این اعداد در پایتون توسط اشیایی با نوع complex ارایه می‌شوند:

>>> a = 3 + 4j
>>> type(a)
<class 'complex'>

>>> import sys
>>> sys.getsizeof(a)
32

از کلاس ()complex [اسناد پایتون] می‌توان برای ایجاد یک شی complex استفاده کرد. این کلاس الگویی مشابه (complex(real, imag دارد؛ آرگومان‌های نمونه real و imag بیانگر اعدادی هستند که به ترتیب قرار است در بخش‌های حقیقی و موهومی عدد مختلط مورد نظر وجود داشته باشند. اگر هر کدام از آرگومان‌ها ارسال نگردند به صورت پیش‌فرض صفر در نظر گرفته خواهند شد:

>>> a = 3
>>> b = 4

>>> type(a)
<class 'int'>
>>> type(b)
<class 'int'>

>>> complex(a, b)
(3+4j)

>>> type(complex(a, b))
<class 'complex'>
>>> complex(3, 4)
(3+4j)

>>> complex(3)
(3+0j)

>>> complex(0, 4)
4j

>>> complex(4j)
4j
>>> a = 3 + 4j
>>> a
(3+4j)

>>> a = 3.2 + 4j
>>> a
(3.2+4j)

>>> a = 3.0 + 4j
>>> a
(3+4j)

>>> a = 3.0 + 4.0j
>>> a
(3+4j)

همچنین با استفاده از دو صفت real و imag می‌توان بخش‌های حقیقی و موهومی هر شی complex را به دست آورد. توجه داشته باشید که جدا از این که اعداد از چه نوعی در تشکیل یک نوع مختلط شرکت کرده باشند؛ بخش‌های عدد مختلط به صورت عدد ممیز شناور تفکیک می‌گردند:

>>> a = 3 + 4j

>>> a.real
3.0
>>> a.imag
4.0

()complex توانایی دریافت یک رشته عددی و تبدیل آن به عدد مختلط را نیز دارد. تنها باید توجه داشت که نباید داخل این رشته هیچ فضای خالی وجود داشته باشد:

>>> a = "3+4j"

>>> type(a)
<class 'str'>

>>> complex(a)
(3+4j)

>>> a = "3"
>>> complex(a)
(3+0j)

>>> type(complex(a))
<class 'complex'>
>>> a = "3 + 4j"
>>> complex(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: complex() arg is a malformed string
>>>

توجه

امکان قرار دادن رشته عددی (مختلط) یا خود شی عدد مختلط در آرگومان کلاس‌های ()int (یا ()long) و ()float وجود ندارد و موجب بروز خطا می‌شود.

دسیمال

اساس طراحی این نوع برای استفاده در مواقعی است که خطا نوع ممیز شناور قابل گذشت نیست [PEP 327] مانند توسعه برنامه حسابداری. مفسر پایتون برای ارایه نوع ممیز شناور به کامپیوتر از کدگذاری Binary Floating-Point (استاندارد IEEE 754) استفاده می‌کند. این کدگذاری اعداد در پایه ده که مورد نظر کاربر هستند را - مانند 0.1 - به شکل دقیق ارایه نمی‌دهد؛ به عنوان نمونه عدد 0.1 برابر با عددی نزدیک به 0.10000000000000001 در محاسبات کامپیوتر شرکت داده می‌شود؛ هر چند که این عدد بسیار نزدیک به 0.1 است ولی به هر حال خود آن نیست!. این موضوع ممکن است در برخی موارد موجب خطا منطقی در برنامه گردد:

>>> a = 0.1 + 0.1 + 0.1
>>> a == 0.3
False
>>> a
0.30000000000000004

در نمونه کد بالا کاربر انتظار دارد که عبارت سطر دوم با ارزش درستی True ارزیابی گردد که این اتفاق نمی‌افتد.

در پایتون نوع دسیمال با ایجاد شی از کلاس Decimal درون ماژول decimal در دسترس قرار گرفته است [اسناد پایتون]. به نمونه کد پایین توجه نمایید:

>>> import decimal

>>> a = decimal.Decimal('0.1')
>>> b = decimal.Decimal('0.3')

>>> b == a + a + a
True

>>> type(a)
<class 'decimal.Decimal'>

>>> a
Decimal('0.1')

>>> print(a)
0.1

>>> import sys
>>> sys.getsizeof(a)
104

به شیوه‌های گوناگونی می‌توان شی دسیمال ایجاد کرد:

1
2
3
4
5
6
a = decimal.Decimal(23)                  # Creates Decimal("23")
b = decimal.Decimal("23.45")             # Creates Decimal("23.45")
c = decimal.Decimal("2345e-2")           # Creates Decimal("23.45")
d = decimal.Decimal((1,(2,3,4,5),-2))    # Creates Decimal("-23.45")
e = decimal.Decimal("infinity")
f = decimal.Decimal("NaN")
  • از آنجا که نوع ممیز شناور دقیق نیست؛ این اعداد را حتما به صورت رشته به Decimal ارسال نمایید (سطر دوم).
  • اعداد را می‌توان به صورت یک شی تاپل (Tuple) - ساختاری مشابه: (... ,Ο, Ο, Ο) - ارسال کرد (سطر چهارم). شیوه نماد علمی را به یاد بیاورید؛ تاپل مورد نظر باید ساختاری مشابه الگو (sign, digits, exponent) داشته باشد که در آن sign مثبت بودن (توسط عدد صفر) یا منفی بودن (توسط عدد یک) را مشخص می‌کند، digits خود تاپلی است که رقم‌های دخیل را بیان می‌کند و exponent نیز بیانگر همان توان است.

میزان دقت (Precision) و عمل گرد کردن (Rounding) اعداد از نوع دسیمال با استفاده از یک شی Context قابل کنترل است؛ این شی یک سری اطلاعات پیکربندی را در اختیار اشیا دسیمال قرار می‌دهد که برای دسترسی به آن باید از تابع ()getcontext [اسناد پایتون] درون ماژول decimal استفاده کرد. تابع ()getcontext شی Context اشیا دسیمال جاری برنامه را برمی‌گرداند. در برنامه‌نویسی چندنخی (Multithreading) هر نخ (thread) شی Context خاص خود را دارد؛ بنابراین این تابع شی Context مربوط به نخ فعال را برمی‌گرداند:

>>> import decimal

>>> a = decimal.Decimal('3.45623')
>>> b = decimal.Decimal('0.12')

>>> a + b
Decimal('3.57623')

>>> print(a + b)
3.57623

>>> ctx = decimal.getcontext()
>>> type(ctx)
<class 'decimal.Context'>

>>> ctx.prec = 1
>>> a + b
Decimal('4')

>>> ctx.prec = 2
>>> a + b
Decimal('3.6')

>>> ctx.prec = 3
>>> a + b
Decimal('3.58')

همانطور که در نمونه کد بالا مشاهده می‌شود دقت محاسبات اعداد دسیمال را می‌توان با استفاده از صفت prec شی Context به شکل دلخواه تنظیم نمود؛ مقدار پیش‌فرض این صفت 28 است. بدیهی است برای اینکه اعداد در محدوده دقت کوچکتری نسبت به طول خود قرار بگیرند نیاز به گرد شدن دارند؛ برای تنطیم عمل گرد کردن در اعداد دسیمال نیز از صفت rounding که مقدار پیش‌فرض آن "ROUND_HALF_EVEN" است، استفاده می‌شود:

>>> a = decimal.Decimal('2.0')
>>> b = decimal.Decimal('0.52')

>>> ctx.prec
28
>>> ctx.rounding
'ROUND_HALF_EVEN'

>>> print(a + b)
2.52

>>> ctx.prec = 2

>>> print(a + b)
2.5

>>> ctx.rounding = "ROUND_CEILING"

>>> print(a + b)
2.6

صفت rounding می‌بایست حاوی مقادیر ثابتی به شرح پایین باشد:

  • ROUND_CEILING - گرد کردن به سمت مثبت بی‌نهایت: یعنی برای اعداد مثبت ارقام خارج از محدوده حذف می‌گردند و آخرین رقم باقی مانده یک واحد افزایش می‌یابد مثلا عدد 2.52 به 2.6 گرد می‌شود. برای اعداد منفی نیز تنها اعداد خارج از محدوده حذف می‌گردند مثلا عدد 2.19- به 2.1- گرد می‌شود.
  • ROUND_FLOOR - گرد کردن به سمت منفی بی‌نهایت: یعنی برای اعداد منفی ارقام خارج از محدوده حذف می‌گردند و آخرین رقم باقی مانده یک واحد افزایش می‌یابد مثلا عدد 2.52- به 2.6- گرد می‌شود. برای اعداد مثبت نیز تنها اعداد خارج از محدوده حذف می‌گردند مثلا عدد 2.19 به 2.1 گرد می‌شود.
  • ROUND_DOWN - گرد کردن به سمت صفر: یعنی برای اعداد مثبت و منفی تنها ارقام خارج از محدوده حذف می‌گردند مثلا عدد 2.58 به 2.5 و عدد 2.58- به 2.5- گرد می‌شود.
  • ROUND_UP - گرد کردن به دور از صفر: یعنی برای اعداد مثبت و منفی ارقام خارج از محدوده حذف می‌گردند و آخرین رقم باقی مانده یک واحد افزایش می‌یابد مثلا عدد 2.52 به 2.6 و عدد 2.52- به 2.6- گرد می‌شود.
  • ROUND_HALF_DOWN - اگر رقم ابتدایی بخش حذف شده بزرگتر از 5 باشد به روش ROUND_UP و در غیر این صورت به روش ROUND_DOWN گرد می‌گردد. مثلا عدد 2.58 به 2.6 و عدد 2.55 به 2.5 گرد شده و همینطور عدد 2.58- به 2.6- و عدد 2.55- به 2.5- گرد می‌شود.
  • ROUND_HALF_UP - اگر رقم ابتدایی بخش حذف شده بزرگتر یا برابر 5 باشد به روش ROUND_UP و در غیر این صورت به روش ROUND_DOWN گرد می‌گردد. مثلا عدد 2.55 به 2.6 و عدد 2.51 به 2.5 گرد شده - همینطور عدد 2.55- به 2.6- و عدد 2.51- به 2.5- گرد می‌کند.
  • ROUND_HALF_EVEN - همانند ROUND_HALF_DOWN است ولی در مواقعی که رقم ابتدایی بخش حذف شده برابر 5 باشد رفتار آن متفاوت می‌شود: در این حالت اگر آخرین رقم باقی مانده زوج باشد به شیوه ROUND_DOWN و اگر فرد باشد به روش ROUND_UP گرد می‌گردد. مثلا عدد 2.68 به 2.7، 2.65 به 2.6 و 2.75 به 2.8 - همینطور عدد 2.68- به 2.7-، 2.65- به 2.6- و 2.75- به 2.8- گرد می‌کند.
  • ROUND_05UP - اگر بر اساس روش ROUND_DOWN آخرین رقم باقی مانده 0 یا 5 باشد؛ به روش ROUND_UP و در غیر این صورت به همان شیوه ROUND_DOWN گرد می‌کند. مثلا عدد 2.58 به 2.6 و 2.48 به 2.4 - همینطور عدد 2.58- به 2.6- و 2.48- به 2.4- گرد می‌شود.

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

کسر

این نوع برای پشتیبانی اعداد گویا (Rational) در پایتون ارایه شده است و با ایجاد شی از کلاس Fraction درون ماژول fractions در دسترس قرار می‌گیرد [اسناد پایتون]:

>>> import fractions

>>> a = 1
>>> b = 2
>>> f = fractions.Fraction(a, b)

>>> f
Fraction(1, 2)

>>> print(f)
1/2

>>> type(f)
<class 'fractions.Fraction'>

>>> import sys
>>> sys.getsizeof(f)
56

علاوه‌بر روش بالا که به صورت مستقیم صورت و مخرج کسر - از نوع صحیح - مشخص شده است؛ به روش‌های دیگری نیز می‌توان یک شی کسری ایجاد نمود:

  • از یک شی ممیز شناور - بهتر است این نوع به صورت رشته وارد شود:

    >>> print(fractions.Fraction('0.5'))
    1/2
    >>> print(fractions.Fraction('1.1'))
    11/10
    >>> print(fractions.Fraction('1.5'))
    3/2
    >>> print(fractions.Fraction('2.0'))
    2
    
    >>> print(fractions.Fraction(0.5))
    Fraction(1, 2)
    
    >>> print(fractions.Fraction(1.1))
    2476979795053773/2251799813685248
    >>> 2476979795053773 / 2251799813685248
    1.1
    
    >>> print(fractions.Fraction(1.5))
    3/2
    

    متد ()limit_denominator می‌تواند یک شی ممیز شناور را با محدود کردن مخرج در یک مقدار بیشینه به صورت تقریبی به یک شی کسر تبدیل نماید:

    >>> fractions.Fraction(1.1).limit_denominator()
    Fraction(11, 10)
    
    >>> import math
    >>> math.pi
    3.141592653589793
    >>> pi = math.pi
    >>> fractions.Fraction(pi)
    Fraction(884279719003555, 281474976710656)
    >>> 884279719003555 / 281474976710656
    3.141592653589793
    
    >>> fractions.Fraction(pi).limit_denominator()
    Fraction(3126535, 995207)
    >>> 3126535 / 995207
    3.1415926535886505
    
    >>> fractions.Fraction(pi).limit_denominator(8)
    Fraction(22, 7)
    >>> 22 / 7
    3.142857142857143
    
    >>> fractions.Fraction(pi).limit_denominator(60)
    Fraction(179, 57)
    >>> 179 / 57
    3.1403508771929824
    
  • از یک شی دسیمال:

    >>> print(fractions.Fraction(decimal.Decimal('1.1')))
    11/10
    
  • از یک رشته کسری - صورت و مخرج کسر می‌بایست از نوع صحیح باشند:

    >>> print(fractions.Fraction('3/14'))
    3/14
    
  • از یک شی کسر دیگر:

    >>> f1 = fractions.Fraction(1, 2)
    >>> f2 = fractions.Fraction(3, 5)
    >>> fractions.Fraction(f1)
    Fraction(1, 2)
    >>> fractions.Fraction(f1, f2)
    Fraction(5, 6)
    

با استفاده از دو صفت numerator و denominator می‌توان به ترتیب به صورت و مخرج شی کسر دسترسی یافت:

>>> f = fractions.Fraction('1.5')
>>> f.numerator
3
>>> f.denominator
2

از این نوع شی به سادگی می توان در انواع محاسبات ریاضی استفاده کرد؛ برای نمونه به تکه کد پایین توجه نمایید:

>>> fractions.Fraction(1, 2) + fractions.Fraction(3, 4)
Fraction(5, 4)

>>> fractions.Fraction(5, 16) - fractions.Fraction(1, 4)
Fraction(1, 16)

>>> fractions.Fraction(3, 5) * fractions.Fraction(1, 2)
Fraction(3, 10)

>>> fractions.Fraction(3, 16) / fractions.Fraction(1, 8)
Fraction(3, 2)

چنانچه یک شی صحیح به شی کسر افزوده شود حاصل یک شی کسر است ولی اگر یک شی ممیز شناور به شی کسر افزوده شود حاصل یک شی از نوع ممیز شناور می‌باشد:

>>> fractions.Fraction(5, 2) + 3
Fraction(11, 2)
>>> fractions.Fraction(5, 2) + 3.0
5.5

ب.م.م

ماژول fractions علاوه بر نوع کسری؛ حاوی تابع ()gcd [اسناد پایتون] نیز است. این تابع «بزرگترین مقسوم‌علیه مشترک» (GCD) دو عدد را برمی‌گرداند:

>>> import fractions
>>> fractions.gcd(54, 24)
6

بولی

کلاسی که در پایتون از آن برای ایجاد شی بولی استفاده می‌شود (bool) در واقع یک کلاس فرزند از کلاس اعداد صحیح (int) است. این نوع شی تنها می‌تواند یکی از دو مقدار True (درست) یا False (نادرست) را داشته باشد که True برابر با عدد صحیح 1 و False برابر با عدد صحیح 0 ارزیابی می‌گردد:

>>> a = True

>>> a
True

>>> type(a)
<class 'bool'>

>>> import sys
>>> sys.getsizeof(a)
28
>>> int(True)
1
>>> int(False)
0
>>> float(True)
1.0
>>> complex(True)
(1+0j)
>>> True + 1
2
>>> False + 1
1
>>> True * 25
25
>>> False * 25
0

کلاس ()bool یا متد ()__bool__ مقدار بولی یک شی را برمی‌گرداند [اسناد پایتون]:

>>> bool(0)
False
>>> bool(1)
True
>>> bool("")   # Empty String
False
>>> a = 15
>>> a.__bool__()
True
>>> a = -15
>>> a.__bool__()
True
>>> a = 0
>>> a.__bool__()
False

در پایتون اشیا پایین به مقدار بولی False (نادرست) ارزیابی می‌گردند:

  • None
  • False
  • شی صفر (در انواع گوناگون): 0، 0.0، 0j
  • تمام اشیا دنباله‌ خالی: ""، ()، []
  • شی دیکشنری خالی: {}
  • شی مجموعه خالی: ()set

با موارد نا آشنا به مرور آشنا می‌شوید.

رشته

نوع «رشته» (String) در پایتون با قرار گرفتن دنباله‌ای از کاراکترها درون یک جفت نماد نقل قول (Quotation) تکی ' ' یا دو تایی " " ایجاد می‌شود؛ به مانند "Python Strings" یا 'Python Strings' که تفاوتی با یکدیگر از نظر نوع ندارند:

>>> a = "Python Strings"

>>> a
'Python Strings'

>>> print(a)
Python Strings

>>> import sys
>>> sys.getsizeof(a)
63

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

در پایتون برخلاف برخی از زبان‌ها نوع کاراکتر یا char وجود ندارد؛ در این زبان یک کاراکتر چیزی جز یک رشته با طول یک نیست.

در پایتون می‌توان از نمادهای نقل قول در داخل یکدیگر نیز بهره برد؛ در این شرایط تنها می‌بایست نماد نقل قول داخلی با بیرونی متفاوت باشد. چنانچه می‌خواهید از نماد نقل قول یکسانی استفاده نمایید، باید از کاراکترهای Escape کمک بگیرید که در ادامه بررسی خواهند شد:

>>> "aaaaaa 'bbb'"
"aaaaaa 'bbb'"
>>> 'aaaaaa "bbb"'
'aaaaaa "bbb"'

>>> "I'm cold!"
"I'm cold!"
>>> 'I\'m cold!'
"I'm cold!"

از درس پیش با Docstring آشنا شده‌ایم؛ در کاربردی دیگر از سه نماد نقل قول """ یا ''' برای ایجاد شی رشته نیز استفاده می‌شود. مزیت این نوع رشته در این است که می‌توان متن آن را به سادگی در چند سطر و با هر میزان تورفتگی دلخواه نوشت؛ این موضوع در زمان‌هایی که قصد استفاده از کدهای خاص به مانند HTML در برنامه خود داشته باشیم، بسیار مفید خواهد بود:

>>> a = """Python"""
>>> a
'Python'
>>> html = """
... <!DOCTYPE html>
... <html>
...     <head>
...         <title>Page Title</title>
...     </head>
...     <body>
...         <h1>This is a Heading.</h1>
...         <p>This is a paragraph.</p>
...     </body>
... </html>
... """
>>> print(html)

<!DOCTYPE html>
<html>
    <head>
        <title>Page Title</title>
    </head>
    <body>
        <h1>This is a Heading.</h1>
        <p>This is a paragraph.</p>
    </body>
</html>

>>>

دنباله‌ها

برخی از انواع شی پایتون به مانند رشته، تاپل (tuple)، لیست (list) و... با عنوان دنباله (Sequence) نیز شناخته می‌شوند. دنباله ویژگی‌هایی دارد که در اینجا به کمک نوع رشته بررسی خواهیم کرد. رشته در واقع یک دنباله از کاراکترهاست در نتیجه می‌توان هر یک از اعضای این دنباله را با استفاده از اندیس (Index) موقعیت آن دستیابی نمود؛ اندیس اعضا از سمت چپ با عدد صفر شروع و به سمت راست یک واحد یک واحد افزایش می‌یابد. به عنوان نمونه برای شی 'Python Strings' می‌توانیم شمای اندیس‌گذاری را به صورت پایین در نظر بگیریم:

P y t h o n   S t r i n g s
- - - - - - - - - - - - - -
0 1 2 3 4 5 6 7  ...      13

برای دستیابی اعضای یک دنباله با نام seq از الگو [seq[i که i اندیس عضو مورد نظر است؛ استفاده می‌شود:

>>> a = "Python Strings"
>>> a[0]
'P'
>>> a[7]
'S'
>>> a[6]
' '

چند نکته:

  • الگو [seq[-i اعضا دنباله را از سمت راست پیمایش می کند؛ اندیس سمت راست ترین عضو 1- است و به ترتیب به سمت چپ یک واحد یک واحد کاهش می‌یابد.
  • الگو [seq[i:j اعضایی از دنباله را که در بازه‌ای از اندیس i تا قبل از اندیس j هستند را دستیابی می‌کند. برای بیان نقاط «از ابتدا» و «تا انتها» می‌توان به ترتیب i و j را ذکر نکرد.
  • الگو [seq[i:j:k همانند قبلی است با این تفاوت که k اندازه گام پیمایش اعضا را تعیین می‌کند.
  • با استفاده از تابع ()len می‌توان تعداد اعضای یک دنباله را به دست آورد [اسناد پایتون].
>>> a = "Python Strings"

>>> len(a)
14

>>> a[-2]
'g'

>>> a[2:4]
'th'
>>> a[7:]
'Strings'
>>> a[:6]
'Python'
>>> a[:-1]
'Python String'

>>> a[2:12:3]
'tntn'
>>> a[:6:2]
'Pto'
>>> a[7::4]
'Sn'

>>> a[-1]
's'
>>> a[len(a)-1]
's'

باید توجه داشت که یک شی رشته جزو انواع immutable پایتون است و مقدار (یا اعضا دنباله) آن را نمی‌توان تغییر داد؛ برای مثال نمی‌توان شی 'Python Strings' به 'Python-Strings' تغییر داد - برای این کار تنها می‌بایست یک شی جدید ایجاد کرد:

>>> a = "Python Strings"
>>> a[6] = "-"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

عملگرها برای رشته

با رشته‌ها نیز می‌توان از عملگرهای + (برای پیوند رشته‌ها) و * (برای تکرار رشته‌ها) بهره برد:

>>> a = "Python" + " " + "Strings"
>>> a
'Python Strings'

>>> "-+-" * 5
'-+--+--+--+--+-'

برای پیوند می‌توان از عملگر + صرف نظر کرد و تنها با کنار هم قرار دادن رشته‌ها آن‌ها را پیوند داد؛ البته این روش در مواقعی که از متغیر استفاده می‌کنید درست نمی‌باشد:

>>> "Python " "Programming " "Language"
'Python Programming Language'
>>> a, b, c = "Python ", "Programming ", "Language"
>>> a + b + c
'Python Programming Language'

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

>>> a = "py"
>>> b = "PY"    # Uppercase
>>> a == b
False

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

>>> "n" in "python"
True
>>> "py" not in "python"
False

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

کاراکترهای Escape

به صورت پیش‌فرض تعدادی کاراکتر خاص تعریف شده است که می‌توان آن‌ها را درون رشته‌ها بکار برد. تمام این کاراکترها با یک \ آغاز می‌شوند به همین دلیل گاهی نیز به نام Backslash Characters خوانده می‌شوند. در واقع این کاراکترها امکانی برای درج برخی دیگر از کاراکترها هستند که نمی‌توان آن‌ها را به سادگی توسط صفحه‌کلید وارد کرد. برای نمونه یکی از کاراکترهای Escape رایج n\ است که بیانگر کاراکتری با کد اسکی 10 (LF) به نام newline می‌باشد؛ n\ در هر جایی از رشته (یا متن) که درج گردد در هنگام چاپ سطر جاری را پایان می‌دهد و ادامه رشته (یا متن) از سطر جدید آغاز می‌‌شود [اسناد پایتون]:

>>> a = "Python\nProgramming\nLanguage"
>>> a
'Python\nProgramming\nLanguage'
>>> print(a)
Python
Programming
Language
>>>

برخی از این کاراکترها به شرح پایین است:

  • n\ - پایان سطر جاری و رفتن به سطر جدید
  • t\ - برابر کد اسکی 9 (TAB): درج هشت فاصله (کلید Space)
  • uxxxx\ - درج یک کاراکتر یونیکد 16 بیتی با استفاده از مقدار هگزادسیمال (پایه شانزده) آن : "u067E\"
  • Uxxxxxxxx\ - درج یک کاراکتر یونیکد 32 بیتی با استفاده از مقدار هگزادسیمال (پایه شانزده) آن : "U0001D11E\"
  • ooo\ - درج یک کاراکتر با استفاده از مقدار اُکتال (پایه هشت) آن : "123\"
  • xhh\ - درج یک کاراکتر با استفاده از مقدار هگزادسیمال (پایه شانزده) آن : "x53\"
  • '\ - درج یک کاراکتر '
  • "\ - درج یک کاراکتر "
  • \\ - درج یک کاراکتر \

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

>>> fpath = "C:\new\text\sample.txt"

>>> print(fpath)
C:
ew        ext\sample.txt

برای حل مشکل نمونه کد بالا می‌توان هر جا که نیاز به \ است از \\ استفاده کرد: "C:\\new\\text\\sample.txt". ولی راهکار جامع‌تر ایجاد «رشته‌های خام» (Raw Strings) است؛ در این نوع رشته‌، کاراکترهای Escape بی‌اثر هستند. رشته خام با افزوده شدن یک حرف r یا R به ابتدای یک رشته معمولی ایجاد می‌گردد:

>>> fpath = r"C:\new\text\sample.txt"
>>> print(fpath)
C:\new\text\sample.txt

تبدیل کد به کاراکتر و برعکس

می‌دانیم برای اینکه کامپیوتر بتواند کاراکتر‌ها را درک کند نیاز به سیستم‌هایی است که آن‌ها را برای تبدیل به کدهای پایه دو کدگذاری کند؛ به مانند سیستم اَسکی (ASCII) یا سیستم‌های جامع‌تری مانند UTF-8 که تحت استاندارد یونیکد (Unicode) در دسترس هستند. گاهی نیاز است به این کدها دسترسی داشته باشیم و با کاراکترها بر اساس آن‌ها کار کنیم؛ برای این منظور در پایتون می‌توان از دو تابع ()ord (تبدیل کد به کاراکتر) [اسناد پایتون] و ()chr (تبدیل کاراکتر به کد) [اسناد پایتون] استفاده کرد. تابع ()ord یک رشته تک کاراکتری را گرفته و یک عدد (در پایه ده) که بیانگر کد کاراکتر مورد نظر می‌باشد را برمی‌گرداند. تابع ()chr نیز کد کاراکتری (که می‌بایست عددی در پایه ده باشد) را گرفته و کاراکتر مربوط به آن را برمی‌گرداند:

>>> # Python 3.x - GNU/Linux

>>> ord("A")
65
>>> chr(65)
'A'

>>> int("067E", 16)   # Hexadecimal to Decimal
1662
>>> chr(1662)         # Unicode Character:  1662 -> 067E -> 'پ'
'پ'
>>> ord(_)            # _ is result of the last executed statement  = 'پ'
1662

>>> ord("\U0001D11E")
119070
>>> chr(_)
'𝄞'

از آنجا که نسخه‌های 2x پایتون به صورت پیش‌فرض از کدگذاری تحت استاندارد یونیکد پشتیبانی نمی‌کنند؛ برای گرفتن کاراکتر یونیکد (کاراکترهای خارج از محدوده اَسکی) از کد آن، می‌بایست از تابع جداگانه‌ای با نام ()unichr [اسناد پایتون] استفاده نماییم:

>>> # Python 2.x - GNU/Linux

>>> ord("a")
97
>>> chr(97)
'a'

>>> unichr(1662)
u'\u067e'
>>> print _
پ

>>> ord(u"\U0001D11E")
119070
>>> unichr(_)
u'\U0001d11e'
>>> print _
𝄞

تبدیل به نوع رشته

برای تبدیل اشیایی از نوع دیگر به نوع رشته؛ کلاس ()str [اسناد پایتون] و تابع ()repr [اسناد پایتون] وجود دارد. کلاس ()str یک نمونه غیر رسمی (informal) از نوع شی رشته را برمی‌گرداند؛ غیر رسمی از این جهت که توسط آن جزییات شی رشته پنهان می‌شود. اما تابع ()repr یک نمونه رسمی (official) از نوع رشته پایتون را برمی‌گرداند. کمی قبل‌تر راجب تفاوت خروجی print و حالت تعاملی صحبت کردیم؛ در واقع خروجی ()str مناسب برای چاپ است و همانند print جزییات این نوع شی را ارایه نمی‌دهد در حالی که ()repr به مانند حالت تعاملی یک ارايه (representation) کامل از شی رشته را برمی‌گرداند:

>>> str(14)
'14'
>>> repr(14)
'14'

>>> str(True)
'True'
>>> repr(False)
'False'
>>> a = "Python Strings"

>>> str(a)
'Python Strings'
>>> repr(a)
"'Python Strings'"

>>> print(str(a))
Python Strings
>>> print(repr(a))
'Python Strings'

همچنین به جای این دو می‌توانید از متدهای ()__str__ و ()__repr__ استفاده نمایید:

>>> a = 10
>>> a.__str__()
'10'

قالب‌بندی رشته‌ (String Formatting)

قالب‌بندی امکانی برای جایگزین کردن یک یا چند مقدار (به بیان بهتر: شی) - گاهی همراه با اعمال تغییر دلخواه - درون یک رشته است که به دو شکل در پایتون پیاده‌سازی می‌گردد [اسناد پایتون]:

۱. قالب سنتی - با الگو (s..." % (values%..."

از دو بخش تشکیل شده است؛ بخش سمت چپ عملگر %، رشته‌ای را مشخص می‌کند که شامل یک یا چند کد جایگذاری شی می‌باشد - کدهای جایگذاری همگی با یک کاراکتر % شروع می‌شوند؛ مانند: s% - و در سمت راست آن شی‌هایی برای جایگزین شدن در رشته، داخل پرانتز قرار دارد؛ این اشیا به ترتیب از سمت چپ درون رشته جایگذاری می‌گردند:

>>> "Python is %s to learn if you know %s to start!" % ("easy", "where")
'Python is easy to learn if you know where to start!'

برخی از کدهای جایگذاری به شرح پایین است:

  • s% - جایگزینی در قالب یک رشته به شکل خروجی کلاس ()str
  • r% - جایگزینی در قالب یک رشته به شکل خروجی تابع ()repr
  • c% - جایگزینی در قالب یک کاراکتر: یک عدد صحیح که نشانگر کد کاراکتر می‌باشد را به کاراکتر یونیکد تبدیل کرده و درون رشته قرار می دهد.
>>> "%r is a %s language." % ("Python", "programming")
"'Python' is a programming language."

>>> er = 1427
>>> "Error %s!" % (er)
'Error 1427!'

>>> "A, B, C, ... Y, %c" % (90)
'A, B, C, ... Y, Z'
  • d% یا i% - جایگزینی در قالب یک عدد صحیح در پایه ده
  • o% - جایگزینی در قالب یک عدد صحیح در پایه هشت
  • x% - جایگزینی در قالب یک عدد صحیح در پایه شانزده با حروف کوچک
  • X% - جایگزینی در قالب یک عدد صحیح در پایه شانزده با حروف بزرگ
>>> "4 + 4 == %d" % (2*4)
'4 + 4 == 8'

>>> "%d" % (0b0110)
'6'

>>> "%d" % (12.6)
'12'

>>> "int('%o', 8) == %d" % (0o156, 0o156)
"int('156', 8) == 110"

>>> "15 == %X in HEX" % (15)
'15 == F in HEX'
  • f% - جایگزینی در قالب یک عدد ممیز شناور (دقت پیش‌فرض: ۶) در پایه ده
  • F% - همانند f% ؛ با این تفاوت که nan و inf را به شکل NAN و INF درج می‌کند.
  • e% - جایگزینی در قالب یک عدد ممیز شناور به شکل نماد علمی با حرف کوچک
  • E% - جایگزینی در قالب یک عدد ممیز شناور به شکل نماد علمی با حرف بزرگ
>>> "%f" % (12.526)
'12.526000'

>>> "%f" % (122e-3)
'0.122000'

>>> "%E" % (12.526)
'1.252600E+01'

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

>>> '%(qty)d more %(product)s' % {'product': 'book', 'qty': 1}
'1 more book'


>>> reply = """
... Greetings...
... Hello %(name)s!
... Your age is %(age)s
... """
>>> values = {'name': 'Bob', 'age': 40}
>>> print(reply % values)

Greetings...
Hello Bob!
Your age is 40

>>>

در اصل می‌توان برای بخش سمت چپ این قالب، ساختاری مانند پایین را در نظر گرفت:

%[(keyname)][flags][width][.precision]typecode
  • در هر استفاده وجود هر یک از []ها اختیاری است یا بستگی به مورد استفاده دارد.
  • (keyname) - درج کلید داخل پرانتز - در مواقع استفاده از شی دیکشنری آورده می‌شود.
  • flags - می‌تواند یکی از سه نماد +، و 0 باشد. + موجب درج علامت عدد می‌شود (علامت اعداد منفی به صورت پیش‌فرض درج می‌گردد؛ این علامت بیشتر برای درج علامت اعداد مثبت به کار می‌رود)، موجب چپ‌چین شدن مقدار می‌گردد (حالت پیش‌فرض راست‌چین است) و 0 تعیین می‌کند که فضای خالی اضافی با صفر پر گردد (در حالت پیش‌فرض Space گذاشته می‌شود).
  • width - اندازه رشته را تعیین می‌کند؛ در مواردی که اندازه تعیین شده بیشتر از اندازه واقعی مقدار باشد، فضای اضافی را می‌توان با صفر یا فضای خالی (Space) پر کرد و البته زمانی که کمتر تعیین گردد، این گزینه نادیده گرفته می‌شود.
  • precision. - در مورد اعداد ممیز شناور، دقت یا تعداد ارقام بعد از ممیز را تعیین می‌کند (دقت پیش‌فرض: ۶). در مواردی که تعداد تعیین شده کمتر از تعداد واقعی ارقام بعد ممیز باشد، عدد گِرد می‌گردد. به وجود . پیش از آن توجه نمایید.
  • typecode - بیانگر همان حرف تعیین کننده نوع کد جایگذاری می‌باشد.
  • به جای width و precision. می توان از * استفاده کرد که در این صورت عدد مربوط به آن‌ها نیز در بخش سمت راست آورده می‌شود و شی جایگزینی می‌بایست درست پس از آن ذکر گردد. این گزینه در مواقعی که لازم است این اعداد در طول اجرای برنامه تعیین گردند کاربرد دارد.
>>> "%6d" % (256)    # typecode='d' width='6'
'   256'

>>> "%-6d" % (256)   # typecode='d' width='6' flags='-'
'256   '

>>> "%06d" % (256)   # typecode='d' width='6' flags='0'
'000256'

>>> "%+d" % (256)    # typecode='d' flags='+'
'+256'
>>> "%10f" % (3.141592653589793)      # typecode='f' width='10'
'  3.141593'

>>> "%10.4f" % (3.141592653589793)    # typecode='f' precision='4' width='10'
'    3.1416'

>>> "%10.8f" % (3.141592653589793)    # typecode='f' precision='8' width='10'
'3.14159265'

>>> "%-10.0f" % (3.141592653589793)   # typecode='f' precision='0' width='10' flags='-'
'3         '
>>> "%*d" % (5, 32)                                  # typecode='d' width='5'
'   32'

>>> "%d %*d %d" % (1, 8, 8231, 3)
'1     8231 3'

>>> "%f, %.2f, %.*f" % (1/3.0, 1/3.0, 4, 1/3.0)
'0.333333, 0.33, 0.3333'

>>> n = """
... %15s : %-10s
... %15s : %-10s
... """
>>> v = ("First name", "Richard", "Last name",  "Stallman")
>>> print(n % v)

     First name : Richard
      Last name : Stallman

>>>

۲. قالب جدید، فراخوانی متد ()format - با الگو (format(values."...{}..."

در این قالب که در نسخه‌های 2.6، 2.7 و 3x پایتون در دسترس است؛ اشیا، آرگومان‌های یک متد مشخص هستند و با استفاده اندیس موقعیت‌ یا نام آن‌ها داخل {} در رشته جایگذاری می‌گردند:

>>> '{0} {1} {2}'.format("Python", "Programming", "Language")
'Python Programming Language'
>>> reply = """
... Greetings...
... Hello {name}!
... Your age is {age}
... """
>>> print(reply.format(age=40, name='Bob'))

Greetings...
Hello Bob!
Your age is 40

>>>
>>> "{0} version {v}".format("Python", v="3.4")
'Python version 3.4'

ملاحظه

همانطور که در درس تابع‌ خواهیم آموخت؛ بدون نیاز به رعایت ترتیب می‌توان آرگومان‌ها را با انتساب مقدار مورد نظر به آن‌ها ارسال نمود.

با هر ترتیبی می‌توان اشیا را جایگذاری نمود:

>>> '{2}, {1}, {0}'.format('a', 'b', 'c')
'c, b, a'

از نسخه 2.7 و بالاتر چنانچه بخواهیم اشیا به ترتیبی که در آرگومان متد قرار دارد جایگذاری شوند؛ نیازی به ذکر اندیس یا نام آرگومان نمی‌باشد:

>>> '{}, {}, {}'.format('a', 'b', 'c')   # 2.7+ only
'a, b, c'

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

>>> '{2}, {1}, {0}'.format(*'abc')
'c, b, a'

>>> '{2}, {1}, {0}'.format(*'python')
't, y, p'

>>> '{2}, {1}, {0}'.format('z', *'abc')
'b, a, z'

بخش درون رشته این قالب نیز ساختاری مشابه پایین دارد:

{fieldname !conversionflag :formatspec}
  • fieldname - اندیس یا نام آرگومان است.

  • conversionflag! - می‌تواند یکی از حروف r و s باشد که به ترتیب ()repr و ()str را بر روی شی فراخوانی می‌کنند. توجه داشته باشید که این حروف با ! شروع می‌شوند:

    >>> "repr() shows quotes: {!r}; str() doesn't: {!s}".format('test1', 'test2')
    "repr() shows quotes: 'test1'; str() doesn't: test2"
    
  • formatspec: - چگونگی درج شی در رشته را تعیین می‌کند. با : شروع می‌شود و خود ساختاری به مانند پایین دارد:

    [[fill]align][sign][#][0][width][,][.precision][typecode]
    
    • در هر استفاده وجود هر یک از []ها اختیاری است یا بستگی به مورد استفاده دارد.
    • fill - می‌تواند هر کاراکتر قابل چاپی باشد - از این گزینه برای پر کردن فضای خالی که توسط width ایجاد گردیده، استفاده می‌شود.
    • align - می‌تواند یکی از کاراکترهای <، > یا ^ باشد که به ترتیب بیانگر حالت راست‌چین، چپ‌چین و وسط‌چین می‌باشند. width نیز پس از آن‌ها آورده می‌شود که میزان اندازه رشته را تعیین می‌کند.
    >>> '{0:<30}'.format('left aligned')     # align='<' width='30'
    'left aligned                  '
    
    >>> '{0:>30}'.format('right aligned')    # align='>' width='30'
    '                 right aligned'
    
    >>> '{0:^30}'.format('centered')         # align='^' width='30'
    '           centered           '
    
    >>> '{0:*^30}'.format('centered')        # align='^' width='30' fill='*'
    '***********centered***********'
    
    • sign - برای نمایش علامت اعداد کاربرد دارد و می‌تواند یکی از نمادهای +، یا یک فضا خالی (Space) باشد. به این صورت که: + علامت تمام اعداد مثبت و منفی را درج می‌کند و نیز تنها موجب درج علامت اعداد منفی می‌شود. در صورت استفاده از فضای خالی، علامت اعداد منفی درج شده ولی به جای علامت اعداد مثبت یک کاراکتر فضای خالی وارد می‌شود.
    >>> '{0:+f}; {1:+f}'.format(3.14, -3.14)   # typecode='f' sign='+'
    '+3.140000; -3.140000'
    
    >>> '{0:-f}; {1:-f}'.format(3.14, -3.14)   # typecode='f' sign='-'
    '3.140000; -3.140000'
    
    >>> '{0: f}; {1: f}'.format(3.14, -3.14)   # typecode='f' sign=' '
    ' 3.140000; -3.140000'
    
    • برخلاف قالب سنتی، می‌توان تبدیل پایه دو را هم داشته باشیم. تبدیل پایه در این قالب با استفاده از حروف b (پایه دو)، o (حرف اُ کوچک - پایه هشت) و x یا X (پایه شانزده) انجام می‌شود. چنانچه یک نماد # به پیش از آن‌ها افزوده شود، پیشوند پایه نیز درج می‌گردد:

      >>> "int: {0:d};  hex: {0:x};  oct: {0:o};  bin: {0:b}".format(42)
      'int: 42;  hex: 2a;  oct: 52;  bin: 101010'
      
      >>> "int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}".format(42)
      'int: 42;  hex: 0x2a;  oct: 0o52;  bin: 0b101010'
      
    • با استفاده از یک , (کاما Comma) می‌توان یک عدد را سه رقم سه رقم از سمت راست جدا نمود:

      >>> '{0:,}'.format(1234567890)
      '1,234,567,890'
      
    • بخش‌هایی از قالب سنتی در این قالب نیز تعریف شده‌ است. گزینه‌های precision ،typecode. و width به همان صورتی هستند که در قالب سنتی بیان گشته است. البته موارد typecode کمی کمتر است؛ به عنوان نمونه در این قالب کد i وجود ندارد و تنها می‌توان از d برای اعداد صحیح در پایه ده استفاده کرد:

      >>> '{0:06.2f}'.format(3.14159)    # width='6' precision='.2' typecode='f'  and [0]
      '003.14'
      >>> '{0:^8.2f}'.format(3.14159)    # align='^'
      '  3.14  '
      
    • برای بیان درصد می‌توان از % به جای f استفاده کرد:

      >>> points = 19.5
      >>> total = 22
      >>> 'Correct answers: {0:.2%}'.format(points/total)
      'Correct answers: 88.64%'
      
    • در قالب سنتی با استفاده از * می‌توانستیم گزینه‌های خود را در طرف دیگر مقداردهی نماییم؛ در قالب جدید برای این منظور می‌توان مانند کاری که برای جایگذاری اشیا انجام می‌دادیم، از { } استفاده کرده و مقدار گزینه‌ها را در جایگاه آرگومان متد تعریف نماییم:

      >>> text = "Right"
      >>> align = ">"
      >>> '{0:{fill}{align}16}'.format(text, fill=align, align=align)
      '>>>>>>>>>>>Right'
      

برخی از متدهای کاربردی یک شی رشته

  • ()capitalize [اسناد پایتون] - یک کپی از رشته که نخستین حرف آن به صورت بزرگ (Capital) نوشته شده است را برمی‌گرداند:

    >>> a = "python string methods"
    >>> a.capitalize()
    'Python string methods'
    
  • (center(width [اسناد پایتون] - یک عدد صحیح که تعیین کننده اندازه رشته است گرفته و رشته را به صورت وسط‌چین شده درون این بازه برمی‌گرداند. در صورتی که اندازه تعیین شده کوچکتر از اندازه واقعی رشته ((len(string) باشد؛ رشته بدون تغییر بازگردانده می‌شود. این متد یک آرگومان اختیاری هم دارد که توسط آن می‌توان کاراکتری را برای پر کردن فضای خالی تعیین نمود:

    >>> a = "python"
    
    >>> a.center(25)
    '          python         '
    
    >>> a.center(25, "-")
    '----------python---------'
    

    دو متد مشابه دیگر با الگو (rjust(width [اسناد پایتون] و (ljust(width [اسناد پایتون] نیز هستند که به ترتیب برای راست‌چین و چپ‌چین کردن متن رشته استفاده می‌شوند:

    >>> a.rjust(25)
    '                   python'
    
    >>> a.ljust(25, ".")
    'python...................'
    
  • (count(sub [اسناد پایتون] - یک رشته را گرفته و تعداد وقوع آن در رشته اصلی را برمی‌گرداند. این متد دو آرگومان اختیاری نیز دارد [[start[, end,] که می‌توان نقطه شروع و پایان عمل این متد را مشخص نمود:

    >>> a = "python string methods"
    
    >>> a.count("t")
    3
    >>> a.count("tho")
    2
    >>> a.count("tho", 15)              # start=15
    1
    >>> a.count("tho", 0, len(a)-1)     # start=0 end=20 -> len(a)==21 : 0 ... 20
    2
    
  • (endswith(suffix [اسناد پایتون] - یک رشته را گرفته و چنانچه رشته اصلی با آن پایان یافته باشد مقدار True و در غیر این صورت False را برمی‌گرداند. این متد دو آرگومان اختیاری نیز دارد [[start[, end,] که می‌توان نقطه شروع و پایان عمل این متد را مشخص نمود:

    >>> a = "Wikipedia, the free encyclopedia."
    
    >>> a.endswith(",")
    False
    >>> a.endswith(",", 0 , 10)    # start=0 end=10
    True
    >>> a.endswith("pedia.", 14)   # start=14
    True
    
  • (find(sub [اسناد پایتون] - یک رشته را گرفته و اندیس شروع آن را برای نخستین وقوع درون رشته اصلی برمی‌گرداند؛ در صورتی که آرگومان دریافتی در رشته اصلی یافت نشود مقدار 1- برگردانده می‌شود. این متد دو آرگومان اختیاری نیز دارد [[start[, end,] که می‌توان نقطه شروع و پایان عمل این متد را مشخص نمود:

    >>> a = "python programming language"
    
    >>> a.find("language")
    19
    >>> a.find("p")
    0
    >>> a.find("p", 6)               # start=6
    7
    >>> a.find("g", 18, len(a)-1)    # start=18 end=27-1
    22
    >>> a.find("saeid")
    -1
    

    متد مشابه دیگری نیز با الگو (rfind(sub [اسناد پایتون] وجود دارد؛ ولی با این تفاوت که اندیس شروع آرگومان دریافتی را برای آخِرین وقوع درون رشته اصلی برمی‌گرداند:

    >>> a.rfind("p")
    7
    >>> a.rfind("p", 6)
    7
    >>> a.rfind("g", 18, len(a)-1)
    25
    >>> a.rfind("saeid")
    -1
    

    در صورتی که نیازی به اندیس ندارید و تنها می‌خواهید وجود یک رشته را درون رشته‌ای مشخص بررسی نمایید؛ از عملگر in استفاده کنید:

    >>> "language" in a
    True
    >>> "p" in a
    True
    >>> "saeid" in a
    False
    
  • (index(sub [اسناد پایتون] - همانند متد (find(sub است با این تفاوت که اگر آرگومان دریافتی در رشته اصلی یافت نشود یک خطا ValueError را گزارش می‌دهد:

    >>> a = "python programming language"
    
    >>> a.index("python")
    0
    >>> a.index("python", 6)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ValueError: substring not found
    

    متد دیگری نیز با الگو (rindex(sub [اسناد پایتون] وجود دارد که مانند (rfind(sub عمل می‌کند ولی با این تفاوت که اگر آرگومان دریافتی در رشته اصلی یافت نشود یک خطا ValueError را گزارش می‌دهد:

    >>> a.rindex("g", 18, len(a)-1)
    25
    
  • (join(iterable [اسناد پایتون] - یک دنباله با اعضایی تمام از نوع رشته را به صورت آرگومان دریافت می‌کند و با استفاده از رشته اصلی اعضای آن‌ را به یکدیگر پیوند داده و برمی‌گرداند:

    >>> a = "-*-"
    
    >>> a.join("python")
    'p-*-y-*-t-*-h-*-o-*-n'
    
    >>> a.join(['p', 'y', 't', 'h', 'o', 'n'])   # get a list of strings
    'p-*-y-*-t-*-h-*-o-*-n'
    
  • (split(sep [اسناد پایتون] - یک کاراکتر را دریافت کرده و رشته را بر اساس آن از هم جدا کرده و به صورت یک شی لیست (list) برمی‌گرداند. این متد یک آرگومان اختیاری نیز دارد که می توان تعداد عمل جداسازی را تعیین نمود:

    >>> a = "p-y-t-h-o-n"
    
    >>> a.split()
    ['p-y-t-h-o-n']
    
    >>> a.split("-")
    ['p', 'y', 't', 'h', 'o', 'n']
    
    >>> a.split("-", 2)
    ['p', 'y', 't-h-o-n']
    
    >>> '1,2,,3,'.split(',')
    ['1', '2', '', '3', '']
    

    متد مشابه دیگری نیز با الگو (rsplit(sep [اسناد پایتون] وجود دارد ولی با این تفاوت که رشته را از سمت راست پیمایش می‌کند:

    >>> a.rsplit("-")
    ['p', 'y', 't', 'h', 'o', 'n']
    
    >>> a.rsplit("-", 2)
    ['p-y-t-h', 'o', 'n']
    
  • (replace(old, new [اسناد پایتون] - دو رشته به صورت آرگومان دریافت می‌کند؛ در تمام رشته اصلی بخش‌هایی که برابر مقدار آرگومان old هستند را با آرگومان new جایگزین می‌کند و سپس رشته جدید را برمی‌گرداند. این متد یک آرگومان اختیاری نیز دارد که می‌توان تعداد عمل جایگزینی را تعیین نمود:

    >>> a = "He has a blue house and a blue car!"
    
    >>> a.replace("blue", "red")
    'He has a red house and a red car!'
    
    >>> a.replace("blue", "red", 1)
    'He has a red house and a blue car!'
    
  • ()lower [اسناد پایتون] - تمام حروف الفبا انگلیسی موجود در رشته را به حرف کوچک تبدیل می‌کند و برمی‌گرداند:

    >>> "CPython-3.4".lower()
    'cpython-3.4'
    

    برعکس؛ متد ()upper [اسناد پایتون] تمام حروف الفبا انگلیسی موجود در رشته را به حرف بزرگ تبدیل می‌کند و برمی‌گرداند:

    >>> "CPython-3.4".upper()
    'CPYTHON-3.4'
    
  • ()islower [اسناد پایتون] - اگر رشته حداقل شامل یکی از حروف الفبا انگلیسی بوده و تمام حروف الفبا آن به صورت کوچک باشند مقدار True و در غیر این صورت False را برمی‌گرداند:

    >>> "python".islower()
    True
    >>> "python-3.4".islower()
    True
    >>> "Python".islower()
    False
    

    برعکس؛ متد ()isupper [اسناد پایتون] اگر رشته حداقل شامل یکی از حروف الفبا انگلیسی بوده و تمام حروف الفبا آن به صورت بزرگ باشند مقدار True و در غیر این صورت False را برمی‌گرداند:

    >>> "python".isupper()
    False
    >>> "Python".isupper()
    False
    >>> "PYTHON".isupper()
    True
    >>> "PYTHON-3.4".isupper()
    True
    
  • ()isalpha [اسناد پایتون] - اگر رشته حداقل شامل یک کاراکتر بوده و تمام کاراکترهای آن تنها یکی از حروف الفبا انگلیسی (کوچک یا بزرگ) باشند مقدار True و در غیر این صورت False را برمی‌گرداند:

    >>> "python".isalpha()
    True
    >>> "python34".isalpha()
    False
    >>> "python 34".isalpha()
    False
    
  • ()isalnum [اسناد پایتون] - اگر رشته حداقل شامل یک کاراکتر بوده و تمام کاراکترهای آن تنها یکی از عددهای 0 تا 9 یا حروف الفبا انگلیسی (کوچک یا بزرگ) باشند مقدار True و در غیر این صورت False را برمی‌گرداند:

    >>> "python34".isalnum()
    True
    >>> "python3.4".isalnum()
    False
    >>> "python-34".isalnum()
    False
    
  • ()isdigit [اسناد پایتون] - اگر رشته حداقل شامل یک کاراکتر بوده و تمام کاراکترهای آن تنها یکی از عددهای 0 تا 9 باشند مقدار True و در غیر این صورت False را برمی‌گرداند:

    >>> "python34".isdigit()
    False
    >>> "34".isdigit()
    True
    >>> "3.4".isdigit()
    False
    

چگونگی ارايه نوع رشته از موارد اختلاف اساسی در نسخه‌های 2x و 3x پایتون است.

در نسخه‌های 2x یک نوع جامع str که محدود به کدگذاری ASCII است؛ هر دو قالب رشته‌های معمولی و داده‌های باینری (متن‌های کدگذاری شده، فایل‌های مدیا و پیام‌های شبکه) را در بر می‌گیرد - رشته باینری با یک حرف b در آغاز آن‌ مشخص می‌گردد. در این سری از نسخه‌ها نوع دیگری نیز با نام unicode وجود دارد که رشته‌های خارج از محدوده کدگذاری ASCII را در بر می‌گیرد؛ برای ایجاد این نوع اشیا می‌بایست رشته مورد نظر با یک حرف u آغاز گردد:

>>> # python 2.x

>>> a = "python"
>>> type(a)
<type 'str'>

>>> a = b"python"
>>> type(a)
<type 'str'>

>>> a = u"python"
>>> type(a)
<type 'unicode'>

علاوه‌بر قرار دادن حرف u در ابتدای رشته برای ایجاد رشته یونیکد، می‌توان از تابع ()unicode [اسناد پایتون] نیز با مشخص کردن سیستم کدگذاری استفاده کرد:

>>> # python 2.x

>>> u = unicode("python", "utf-8")

>>> type(u)
<type 'unicode'>

>>> u
u'python'

>>> print u
python

>>> fa = u"پ"
>>> fa
u'\u067e'
>>> print fa
پ

بنابراین انواع رشته در پایتون 2x:

  • رشته‌های معمولی (محدود به کدگذاری اَسکی) + داده‌های باینری: str
  • رشته‌های یونیکد : unicode

ولی در نسخه‌های 3x رشته توسط سه نوع ارایه می‌گردد. اکنون کدگذاری پیش‌فرض کاراکترها در پایتون از ASCII بسیار گسترده‌تر شده است و از استاندارد یونیکد پشتیبانی می‌کند بنابراین نوع str به تنهایی می‌تواند تقریبا تمامی کاراکترهای دنیا را شامل شود و دیگر نیازی به نوع جداگانه و استفاده از حرف u برای مشخص کردن رشته‌های یونیکد نیست؛ بنابراین در این نسخه‌ها برای تمام رشته‌های اسکی و یونیکد تنها یک نوع str ارایه شده است. تغییر دیگری نیز رخ داده که نوع داده باینری از رشته‌های معمولی جدا شده است و توسط نوع جدیدی با نام bytes ارایه می‌گردد:

>>> # Python 3.x

>>> a = "python"
>>> type(a)
<class 'str'>

>>> a = b"python"
>>> type(a)
<class 'bytes'>

>>> a = u"python"
>>> type(a)
<class 'str'>

بنابراین انواع رشته در پایتون 3x:

  • رشته‌های معمولی (اَسکی و یونیکد): str
  • داده‌های باینری: bytes
  • نوع تغییر پذیر (Mutable) برای داده‌های باینری: bytearray - این نوع در واقع یک دنباله تغییر پذیر از نوع bytes است که در نسخه‌های 2.6 و 2.7 نیز در دسترس است.

در پایتون 3x برای ایجاد نوع bytes علاوه‌بر حرف b می‌توان از کلاس ()bytes [اسناد پایتون] نیز استفاده کرد که در آرگومان این کلاس برای نوع رشته لازم است که سیستم کدگذاری آن را نیز مشخص نماییم؛ داده‌های عددی را نیز بهتر است به شکل یک شی لیست ارسال نماییم:

>>> # Python 3.x
>>> b = b"python"
>>> b
b'python'
>>> b = bytes("python", "utf-8")
>>> b
b'python'

>>> c = bytes([97])
>>> c
b'a'

اکنون برای تبدیل نوع bytes به str نیاز به کدگشایی یا Decode کردن داده‌ها داریم؛ این کار را می‌توان با استفاده از متد ()decode یا کلاس ()str با مشخص کردن سیستم کدگشایی به انجام رساند:

>>> type(b)
<class 'bytes'>

>>> print(b)
b'python'

>>> b.decode("utf-8")
'python'

>>> str(b, "utf-8")
'python'

همانند کلاس ()bytes این بار برای ایجاد نوع bytearray از کلاس ()bytearray [اسناد پایتون] استفاده می‌شود:

>>> # Python 3.x

>>> b = bytearray("python", "utf-8")

>>> b
bytearray(b'python')

>>> print(b)
bytearray(b'python')

>>> b[0]
112
>>> b[0] = 106           # 106='j'

>>> b.decode("utf-8")
'jython'
>>> str(b, "utf-8")
'jython'


😊 امیدوارم مفید بوده باشه

لطفا دیدگاه و سوال‌های مرتبط با این درس خود را در کدرز مطرح نمایید.