کتابخانه استاندارد
پایتون با «باتریهای همراه» میآید. صدها ماژول آماده همراه نصب پایتون هستند و شما فقط باید بدانید که وجود دارند. این فصل معرفی پرکاربردترینهایشان است.
۱. سه شکل import
ماژول یک فایل پایتون است پر از توابع آماده. برای استفاده از آن باید اول واردش کنید.
# Way 1: import the whole module, then use 'module.name'
import random
print(random.randint(1, 6))
# Way 2: import it under a shorter name
import random as rnd
print(rnd.randint(1, 6))
# Way 3: import only what we need, then use the name directly
from random import randint, choice
print(randint(1, 6))
print(choice(['red', 'green', 'blue']))
# 'from module import *' imports everything. Avoid it: you no longer know
# where a name comes from, and it can silently overwrite your own names.
سه شکل وارد کردن: نمونه 01_import_styles.py
| شکل | استفاده | کی |
|---|---|---|
import random | random.randint(...) | حالت پیشفرض و امنترین |
import random as rnd | rnd.randint(...) | وقتی نام ماژول طولانی است |
from random import randint | randint(...) | وقتی فقط چند تابع لازم دارید |
from random import * | همه چیز | هرگز |
from module import * همه نامهای ماژول را داخل فایل
شما میریزد. اگر ماژول تابعی به نام choice داشته باشد و
شما هم متغیری به همان نام داشته باشید، یکی دیگری را از بین میبرد و
هیچ خطایی هم نمیبینید. بهعلاوه، وقتی کد را میخوانید نمیدانید
randint از کجا آمده است.
هرگز فایل خودتان را random.py یا math.py نگذارید. پایتون اول در پوشه جاری جستوجو میکند، فایل شما را پیدا میکند و به جای ماژول واقعی واردش میکند. نتیجه، خطاهای بسیار گیجکننده است.
۲. عدد تصادفی صحیح
import random
# randint(a, b) -> a whole number between a and b, BOTH included.
x = random.randint(1, 6)
y = random.randint(1, 6)
print(f'{x}, {y}')
# randrange() works like range(): the last value is NOT included.
print(random.randrange(1, 10)) # 1..9
print(random.randrange(0, 100, 5)) # 0, 5, 10, ... 95
عدد تصادفی صحیح: نمونه 02_random_integers.py
تفاوت مهم: در randint هر دو سر بازه شامل
هستند، ولی randrange مثل range عمل میکند و
عدد آخر را شامل نمیشود. برای تاس، randint(1, 6) درست است.
۳. عدد تصادفی اعشاری
import random
# random() -> a decimal number between 0.0 and 1.0 (1.0 excluded)
print(random.random())
# uniform(a, b) -> a decimal number between a and b
print(random.uniform(5, 10))
# A percentage with two decimals:
print(round(random.random() * 100, 2))
عدد تصادفی اعشاری: نمونه 03_random_floats.py
۴. انتخاب تصادفی از یک مجموعه
import random
colors = ['red', 'green', 'blue']
# choice() -> ONE item
print(random.choice(colors))
# sample() -> k DIFFERENT items (no repetition)
print(random.sample(colors, 2))
# choices() -> k items WITH repetition allowed
print(random.choices(colors, k=5))
# choices() can also be given weights.
print(random.choices(colors, weights=[10, 1, 1], k=5))
# shuffle() mixes a list IN PLACE and returns None.
numbers = [1, 2, 3, 4, 5]
random.shuffle(numbers)
print(numbers)
انتخاب تصادفی: نمونه 04_random_choice.py
| تابع | وظیفه آن |
|---|---|
choice(lst) | یک عضو تصادفی |
sample(lst, k) | k عضو متفاوت، بدون تکرار. مثل قرعهکشی |
choices(lst, k=n) | n عضو با امکان تکرار |
choices(..., weights=[...]) | با احتمالهای متفاوت |
shuffle(lst) | بُر زدن خود لیست. چیزی برنمیگرداند |
باز هم آن دام آشنا: shuffle مثل sort خود لیست
را عوض میکند و None برمیگرداند. ننویسید
numbers = random.shuffle(numbers).
۵. دانه تصادفی
import random
# The "random" numbers of a computer are computed from a starting value
# called the seed. With the same seed we always get the same sequence -
# which is exactly what we want while testing a program.
random.seed(42)
print([random.randint(1, 100) for _ in range(5)])
random.seed(42)
print([random.randint(1, 100) for _ in range(5)]) # the same five numbers
# Without a seed, Python uses the current time, so the numbers change.
random.seed()
print([random.randint(1, 100) for _ in range(5)])
دانه: نمونه 05_random_seed.py
اعداد تصادفی کامپیوتر در عمل شبهتصادفی هستند: از یک عدد شروع میشوند و با فرمولی محاسبه میشوند. اگر همان عدد شروع را بدهید، همان دنباله را میگیرید. این برای آزمایش برنامه بسیار مفید است، چون میتوانید باگ را دوباره تولید کنید.
ماژول random برای بازی و شبیهسازی عالی است ولی برای
تولید رمز عبور یا توکن امنیتی مناسب نیست، چون قابل پیشبینی است.
برای آن کارها ماژول secrets ساخته شده است.
۶. بازی تاس
'''A small dice game: the player and the computer roll two dice.'''
import random
def roll_two_dice() -> int:
'Roll two dice and return their total.'
return random.randint(1, 6) + random.randint(1, 6)
def main() -> None:
player_score = 0
computer_score = 0
for round_number in range(1, 4):
input(f'Round {round_number} - press Enter to roll...')
player = roll_two_dice()
computer = roll_two_dice()
print(f'You: {player} Computer: {computer}')
if player > computer:
player_score += 1
print('You win this round!')
elif computer > player:
computer_score += 1
print('The computer wins this round!')
else:
print('Draw.')
print(f'\nFinal score - you: {player_score}, computer: {computer_score}')
if __name__ == '__main__':
main()
بازی تاس: نمونه 06_dice_game.py
نکته ظریف: input() اینجا بدون ذخیره کردن نتیجه به کار رفته
است. فقط میخواهیم برنامه منتظر بماند تا کاربر اینتر بزند. این ترفند
سادهای است برای مکث دادن به برنامههای متنی.
۷. ماژول math
import math
print(math.pi) # 3.141592653589793
print(math.e)
print(math.sqrt(16)) # 4.0 -> square root
print(math.pow(2, 10)) # 1024.0 (a float; the operator ** gives an int)
print(2 ** 10) # 1024
print(math.factorial(5)) # 120
print(math.gcd(12, 18)) # 6 -> greatest common divisor
print(math.floor(3.7)) # 3 -> down
print(math.ceil(3.2)) # 4 -> up
print(math.fabs(-5)) # 5.0
# Area of a circle.
radius = float(input('Radius of the circle: '))
print('Area:', math.pi * radius ** 2)
ماژول math: نمونه 07_math_module.py
در فصلهای قبل فاکتوریل و بزرگترین مقسومعلیه مشترک را با دست نوشتیم. حالا میبینید که هر دو آمادهاند. باز هم همان درس: اول بفهمید چطور کار میکند، بعد از نسخه آماده استفاده کنید.
۸. گرد کردن
import math
value = 3.567
print(round(value)) # 4 -> nearest whole number
print(round(value, 2)) # 3.57 -> two decimals
print(math.floor(value)) # 3 -> always down
print(math.ceil(value)) # 4 -> always up
print(int(value)) # 3 -> simply cuts the decimals
# Careful with negative numbers: int() and floor() are NOT the same.
print(int(-3.7), math.floor(-3.7)) # -3 and -4
# Python uses "banker's rounding": .5 goes to the nearest EVEN number.
print(round(2.5), round(3.5)) # 2 and 4
گرد کردن: نمونه 08_rounding.py
| روش | روی ۳٫۷ | روی منفی ۳٫۷ | معنی |
|---|---|---|---|
round() | ۴ | منفی ۴ | نزدیکترین |
math.floor() | ۳ | منفی ۴ | همیشه به سمت پایین |
math.ceil() | ۴ | منفی ۳ | همیشه به سمت بالا |
int() | ۳ | منفی ۳ | بریدن اعشار، به سمت صفر |
round(2.5) برابر ۲ است، نه ۳. این باگ نیست: پایتون
نصفها را به نزدیکترین عدد زوج گرد میکند. دلیلش
این است که اگر همیشه رو به بالا گرد کنید، در محاسبات مالی بزرگ یک
خطای انباشته ایجاد میشود. اگر رفتار مدرسهای میخواهید، باید
خودتان بنویسید یا از ماژول decimal استفاده کنید.
۹. تاریخ و زمان
from datetime import datetime, date
# The current date and time.
now = datetime.now()
print(now)
print(now.year, now.month, now.day)
print(now.hour, now.minute, now.second)
# Only the date.
today = date.today()
print(today)
# Building a specific date.
birthday = date(2005, 3, 21)
print(birthday)
# strftime() turns a date into text the way we want it.
print(now.strftime('%Y/%m/%d'))
print(now.strftime('%d %B %Y'))
print(now.strftime('%H:%M:%S'))
# strptime() does the opposite: it reads a date out of a text.
parsed = datetime.strptime('2026-09-08', '%Y-%m-%d')
print(parsed)
تاریخ و زمان: نمونه 09_datetime_basics.py
| کد قالب | یعنی |
|---|---|
%Y | سال چهاررقمی |
%m | ماه دورقمی |
%d | روز دورقمی |
%B | نام ماه |
%H:%M:%S | ساعت و دقیقه و ثانیه |
دو تابع را با هم اشتباه نگیرید: strftime تاریخ را به
متن تبدیل میکند و strptime متن را به
تاریخ. حرف f یعنی format و حرف p یعنی parse.
۱۰. اختلاف دو تاریخ
from datetime import date, timedelta
today = date.today()
birthday = date(2005, 3, 21)
# Subtracting two dates gives a timedelta.
age = today - birthday
print('Days lived:', age.days)
print('Approximate age:', age.days // 365)
# Adding a duration to a date.
print('In 100 days:', today + timedelta(days=100))
print('One week ago:', today - timedelta(weeks=1))
# A small program: how many days until the end of the year?
end_of_year = date(today.year, 12, 31)
print('Days left this year:', (end_of_year - today).days)
اختلاف تاریخ: نمونه 10_datetime_difference.py
تفریق دو تاریخ یک timedelta میدهد که یعنی «مدت زمان».
صفت .days تعداد روزهایش را میدهد. برای جمع زدن هم همین
نوع را میسازید و به تاریخ اضافه میکنید.
۱۱. ماژول time
import time
print('Start')
time.sleep(1) # pause the program for one second
print('One second later')
# Measuring how long a piece of code takes.
start = time.time()
total = 0
for i in range(3_000_000):
total += i
end = time.time()
print(f'The loop took {end - start:.3f} seconds.')
# perf_counter() is more precise for measuring short durations.
start = time.perf_counter()
sum(range(3_000_000))
print(f'sum() took {time.perf_counter() - start:.3f} seconds.')
ماژول time: نمونه 11_time_module.py
Start One second later The loop took 0.187 seconds. sum() took 0.043 seconds.
شرح مثال
sleep(n)برنامه را n ثانیه متوقف میکند. برای انیمیشنهای متنی و برای مکث بین درخواستهای شبکه به کار میآید.- اندازهگیری زمان الگوی سادهای دارد: زمان را پیش و پس از کد بگیرید و تفریق کنید.
- نتیجه جالب است:
sum(range(...))چند برابر سریعتر از حلقه دستی است، چون داخل خود پایتون و به زبان C پیادهسازی شده است. - نوشتن
3_000_000با زیرخط کاملاً مجاز است و فقط برای خوانایی است. پایتون زیرخطها را نادیده میگیرد.
۱۲. آرگومانهای خط فرمان
'''Reading the arguments typed on the command line.
Run it like this:
python 12_sys_argv.py 12 30
'''
import sys
def main() -> None:
# sys.argv[0] is the name of the file itself.
print('All the arguments:', sys.argv)
if len(sys.argv) < 3:
print('Usage: python 12_sys_argv.py <number1> <number2>')
sys.exit(1) # stop the program with an error code
num1 = float(sys.argv[1])
num2 = float(sys.argv[2])
print('Sum:', num1 + num2)
if __name__ == '__main__':
main()
خط فرمان: نمونه 12_sys_argv.py
$ python 12_sys_argv.py 12 30 All the arguments: ['12_sys_argv.py', '12', '30'] Sum: 42.0
شرح مثال
sys.argvلیستی از رشتههاست: عضو صفرم نام خود فایل است و بقیه، آرگومانهای کاربر.- همه اعضا رشته هستند، پس مثل
inputباید تبدیلشان کنید. - بررسی طول لیست ضروری است، وگرنه اگر کاربر آرگومان ندهد
IndexErrorمیگیرید. sys.exit(1)برنامه را با کد خطا تمام میکند. عدد صفر یعنی موفقیت و هر عدد دیگری یعنی خطا؛ این قرارداد سیستمعامل است.- برای برنامههای جدی، ماژول
argparseبسیار بهتر است و خودش راهنما و اعتبارسنجی میسازد.
پوشه S16-standard-library شامل نمونههای
01_import_styles.py تا 12_sys_argv.py.
خلاصه فصل
| ابزار | وظیفه آن |
|---|---|
import m / from m import x | وارد کردن ماژول. ستاره را به کار نبرید |
random.randint(a, b) | عدد صحیح تصادفی، هر دو سر شامل |
random.choice sample shuffle | انتخاب و بُر زدن |
random.seed(n) | تکرارپذیر کردن نتیجههای تصادفی |
math.sqrt pi factorial gcd | توابع ریاضی آماده |
round floor ceil int | چهار نوع گرد کردن با رفتار متفاوت |
datetime.now() date.today() | زمان و تاریخ جاری |
strftime strptime | تاریخ به متن و متن به تاریخ |
timedelta | مدت زمان، برای جمع و تفریق تاریخ |
time.sleep perf_counter | مکث و اندازهگیری زمان |
sys.argv | آرگومانهای خط فرمان، همیشه رشته |
تمرینهای فصل شانزده
- بازی حدس عدد را بنویسید که کامپیوتر عددی بین ۱ تا ۱۰۰ انتخاب کند و بگوید بزرگتر یا کوچکتر.
- برنامهای بنویسید که هزار بار تاس بیندازد و بشمارد هر وجه چند بار آمده است.
- یک رمز عبور تصادفی ده کاراکتری از حروف و ارقام و نمادها بسازید.
- برنامهای بنویسید که شش عدد متفاوت بین ۱ تا ۴۹ انتخاب کند، مثل قرعهکشی.
- شعاع دایره را بگیرید و با
mathمساحت و محیطش را چاپ کنید. - تاریخ تولد را بگیرید و سن دقیق را به سال و ماه و روز چاپ کنید.
- تاریخ امروز را در سه قالب مختلف چاپ کنید.
- زمان جمع اعداد یک تا ده میلیون را یک بار با حلقه و یک بار با
sum(range(...))اندازه بگیرید و مقایسه کنید.