PyCoders (پایتون)
Open in Telegram
◇ #پایتون جادوگر دنیای برنامه نویسی! ◇ معرفی حوزه های کاری پایتون ◇ معرفی کتابخونه های کاربردی ◇ معرفی دوره های مفید ◇ معرفی تکنیک ها و نکات ◇ نقشه راه حوزه های مختلف ◇ اخبار و آپدیت های پایتون ◇ و هر چیزی در مورد پایتون! ■ گروه پایتون: @programmers_py
Show more4 106
Subscribers
+324 hours
+47 days
No data30 days
Posts Archive
4 106
🔆 کتاب خوبی برای یادگیری معماری تر و تمیز که برای زبان برنامهنویسی پایتون آموزش داده شده
🔹https://www.thedigitalcatbooks.com/pycabook-introduction
🐍 @python_rd
4 106
🔆 اشتباه رایج در پایتون: لیستهای "سرسخت"!
🔹 خیلی از بچهها موقع تعریف تابع، از لیست یا دیکشنری به عنوان آرگومان پیشفرض استفاده میکنن که باعث میشه باگهای عجیب و غریبی توی پروژه پیش بیاد.
🔹داستان اینه: پایتون آرگومان پیشفرض رو فقط یکبار (موقع تعریف تابع) میسازه، نه هر بار که تابع رو صدا میزنی. نتیجهش این میشه که لیستِ شما بین تمام فراخوانیها مشترک میمونه!
🔹 کد غلط (باگدار):
def add_item(val, my_list=[]):
my_list.append(val)
return my_list
print(add_item(1)) # خروجی: [1]
print(add_item(2)) # خروجی: [1, 2] !!!
🔹کد درست (پایتونیک):
همیشه از None استفاده کن و مقداردهی رو داخل تابع انجام بده:
def add_item(val, my_list=None):
if my_list is None:
my_list = []
my_list.append(val)
return my_list
print(add_item(1)) # خروجی: [1]
print(add_item(2)) # خروجی: [2]
🔹 این یه نکتهی ساده ولی حیاتیه که کدت رو از یه کدِ آماتوری به یه کدِ حرفهای تبدیل میکنه.
🐍 @python_rd4 106
🔆 خیلی از برنامهنویسهای تازهکار هنوز از روشهای قدیمی مثل update() یا پیمایش حلقه استفاده میکنند. اما توی پایتون ۳.۹ به بعد یک اپراتور جذاب اضافه شده!
🔸 روش قدیمی:
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
# روش اول: تغییر روی dict1
dict1.update(dict2)
# روش دوم (پایتون ۳.۵ به بعد):
merged = {**dict1, **dict2}
🔹روش جدید و تمیز (پایتون ۳.۹+):
dict1 = {'a': 1, 'b': 2}
dict2 = {'b': 3, 'c': 4}
# استفاده از اپراتور Union (|)
merged = dict1 | dict2
print(merged)
# Output: {'a': 1, 'b': 3, 'c': 4}
🔹نکته: اگه کلید تکراری وجود داشته باشه (مثل b)، مقدار دیکشنری سمت راست جایگزین میشه.
🐍 @python_rd4 106
🔆 با این کتابخانه پایتون، با یک خط کد دیتای تلگرام/اینستاگرام رو استخراج کن!
🔹 اگه دنبال یک ابزار پرسرعت و راحت برای Scraping یا جمعآوری دیتا از وب هستید، کتابخانه BeautifulSoup و Scrapy رو همه میشناسن؛ اما کتابخانه Selectolax سرعتی تا ۱۰ برابر بیشتر ارائه میده!
🔹 چرا Selectolax؟
پردازش HTML با موتور C (فوقالعاده سریع)
مصرف حافظه بسیار کم نسبت به BeautifulSoup
یادگیری سریع و سینتکس ساده
🔹 نمونه کد ساده:
from selectolax.parser import HTMLParser
html = "<html><body><h1 class='title'>Hello Python!</h1></body></html>"
tree = HTMLParser(html)
node = tree.css_first('h1.title')
print(node.text()) # Output: Hello Python!
🔹به چه دردی میخوره؟
عالی برای پروژههای بزرگ جمعآوری اطلاعات و رباتهای تلگرامی که نیاز به پردازش حجم بالای دیتا دارند.
🐍 @python_rd4 106
🔆 لیست خوبی از مطالب مرتبط با برنامهنویسی فانکشنال با پایتون
🔹 github.com/sfermigier/awesome-functional-python
🐍 @python_rd
4 106
🔆 هیچوقت از لیست یا دیکشنری خالی به عنوان مقدار پیشفرض (Default Value) توی توابع استفاده نکنید!
🔹وقتی در تعریف یک تابع در پایتون، مقداری مثل یک لیست ([]) یا دیکشنری ({}) را بهعنوان مقدار پیشفرض قرار میدهید، پایتون این شیء را فقط یکبار (در زمان تعریف تابع و Load شدن کد) در حافظه میسازد.
🔹 از آنجایی که لیستها و دیکشنریها قابل تغییر (Mutable) هستند، اگر تابع را چند بار بدون پاس دادن ورودی جدید فراخوانی کنید، پایتون هر بار از همان شیء قدیمی در حافظه استفاده میکند. در نتیجه، تغییرات در فراخوانیهای قبلی، روی فراخوانیهای بعدی اثر میگذارد!
🔹 به جای این کد:
#در این کد، لیست users فقط یکبار ساخته میشود و تمام کاربران جدید به همان یک لیست اضافه میشوند.
def add_user(user_name, user_list=[]):
user_list.append(user_name)
return user_list
# فراخوانی اول
print(add_user("امیر"))
# خروجی: ['امیر']
# فراخوانی دوم (بدون پاس دادن لیست جدید)
print(add_user("سارا"))
# خروجی انتظار میرفت ['سارا'] باشه، اما میشه: ['امیر', 'سارا']
🔹 اینجوری بنویس:
#از None به عنوان مقدار پیشفرض استفاده میکنیم و داخل تابع بررسی میکنیم که اگر مقدار None بود، یک لیست جدید ایجاد شود.
def add_user(user_name, user_list=None):
if user_list is None:
user_list = [] # ایجاد لیست جدید در هر بار اجرای تابع
user_list.append(user_name)
return user_list
print(add_user("امیر")) # خروجی: ['امیر']
print(add_user("سارا")) # خروجی: ['سارا'] (کاملاً مستقل و درست!)
🐍 @python_rd4 106
🔆 اگر توی پایتون تابعی داری که محاسبات سنگین انجام میده یا ورودیهای تکراری داره، نیازی نیست هر بار از اول اجرا بشه! با استفاده از دکوراتور lru_cache میتونی خروجیها رو کَش (Cache) کنی.
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(n):
if n < 2:
return n
return fibonacci(n-1) + fibonacci(n-2)
# اجرای این کد بدون lru_cache زمان زیادی میبره.
print(fibonacci(100))
🔹 به چه دردی میخوره؟
این روش برای توابعی عالیه که با ورودی یکسان، همیشه خروجی یکسانی میدن (Pure Functions).
🐍 @pyrhon_rd4 106
🔆 خروجی این تکه کد پایتون چی میشه؟
def add_item(item, my_list=[]):
my_list.append(item)
return my_list
print(add_item(1))
print(add_item(2))
🔹 گزینهها:
۱) [1] و [2]
۲) [1] و [1, 2]
۳) خطا میده
۴) [2] و [2]
🐍 @python_rd4 106
🔆 کتابی در مورد پترنهای ساده برای ساختن اپلیکیشنهای پیچیده با پایتون که به رایگان و آنلاین قابل مطالعه است.
🔹https://www.cosmicpython.com/book/preface.html
🐍 @python_rd
4 106
🌐 دکوریتورها (Decorators) توی پایتون مثل یک «روکش» برای توابع هستن. فرض کن میخوای به چند تا تابع، قابلیت لاگگیری یا زمانسنجی اضافه کنی بدون اینکه کدهای اصلیشون رو تغییر بدی. دکوریتور این کار رو خیلی تمیز برات انجام میده و کدت رو ماژولار نگه میداره.
🔹 مثلاً این کدِ یک زمانسنج سادهست که نشون میده تابع چقدر طول میکشه اجرا بشه:
import time
def timer(func):
def wrapper():
start = time.time()
func()
print(f"زمان اجرا: {time.time() - start:.4f} ثانیه")
return wrapper
@timer
def say_hello():
time.sleep(1)
print("سلام به دنیای پایتون!")
say_hello()
🔹 میبینی که چطور با قرار دادن @timer بالای تابع say_hello، بدون اینکه حتی یک خط از منطق داخل خودِ تابع رو دستکاری کنیم، قابلیت زمانسنجی بهش اضافه شد. هر جا دیدی یه چیزی با @ شروع میشه و بالای تعریف یه تابع نشسته، بدون که داره اون تابع رو با قابلیتهای جدید "دکور" میکنه.
🐍 @python_rd4 106
🔆 ۶ تکنیک طلایی برای نوشتن کدهای پایتونی تمیزتر و حرفهایتر
🔹۱. استفاده از List Comprehension به جای حلقههای طولانی:
به جای نوشتن حلقههای چندخطی برای ساخت لیست، از ساختار تکخطی و خوانای پایتون استفاده کنید تا هم کد سریعتر اجرا شود و هم شلوغی بیهوده کم شود.
🔹۲. مدیریت فایلها و کانکشنها با Context Manager:
استفاده از ساختار
with خیالتان را از بسته شدن خودکار فایلها، کانکشنهای دیتابیس و مدیریت منابع در صورت بروز خطا راحت میکند.
🔹 ۳. نامگذاری بر اساس استانداردهای PEP 8:
نام توابع و متغیرها را با حروف کوچک و زیرخط (snake_case) و نام کلاسها را با حروف بزرگ (PascalCase) بنویسید تا خوانایی پروژه برای همتیمیها حفظ شود.
🔹 ۴. بهرهگیری از Type Hinting:
با مشخص کردن نوع ورودی و خروجی توابع، اشکالزدایی پروژه بسیار سادهتر میشود و ویرایشگر کدهایتان خطاهای نوع داده را سریعتر پیدا میکند.
🔹 ۵. جایگزینی f-string با فرمتهای قدیمی:
فرمتبندی با f-string سریعترین، خواناترین و تمیزترین روش برای الحاق متغیرها به رشتههاست.
🔹 ۶. کنترل خطا با ساختار try-except دقیق:
از بلاکهای کلی except: خودداری کنید و همیشه خطاهای مشخص و احتمالی مثل KeyError یا ValueError را مدیریت کنید تا خطاهای پیشبینینشده مخفی نمانند.
🐍 @python_rd4 106
🔆داکیومنت خوبی برای class-base view توی جنگو که به همراه متدها و attribute های هر قسمت کامل توضیح داده شده.
🔹https://ccbv.co.uk
🐍 @python_rd
4 106
🔆 چرا در پایتون به معنای واقعی نمیتوانیم thread داشته باشیم. توی این مقاله جالب بصورت ملموس در مورد GIL در پایتون صحبت میشه.
🔹https://pythonspeed.com/articles/python-gil
🐍 @python_rd
4 106
🔆 تست پایتون!
x = 10
res = [x for x in range(3)]
print(x)
خروجی چیه؟
۱) 2
۲) 10
۳) UnboundLocalError
۴) None
🐍 @python_rd4 106
🔆 خیلی وقتا توی پایتون کدهایی میبینیم که برای پیمایش روی یک لیست، همزمان با اندیس، میان یه متغیر شمارنده دستی تعریف میکنن یا از
range(len(items)) استفاده میکنن.
🔹روش تمیز و پایتونیک برای این کار، استفاده از enumerate هست. این تابع به شما اجازه میده هم اندیس و هم خود آیتم رو بهصورت تاپل دریافت کنید و حتی اندیس شروع رو هم مشخص کنید:
fruits = ['apple', 'banana', 'orange']
for index, fruit in enumerate(fruits, start=1):
print(f"{index}: {fruit}")
🔹هم کد خواناتر میشه و هم احتمال خطاهای دستی به صفر میرسه
🐍 @python_rd4 106
🔆 قابلیت کاربردی و کمتر دیده شده (functools.singledisplay)
🔹 اگر توی پایتون کدی داری که بر اساس نوع داده ورودی (int, list, str و...) رفتارهای متفاوتی نشون میده، بهجای نوشتن if-elif-else های طولانی و کثیف، میتونی از دکوراتور فوقالعاده singledispatch استفاده کنی!
from functools import singledispatch
# تابع اصلی برای حالت پیشفرض
@singledispatch
def process(data):
raise NotImplementedError("نوع داده پشتیبانی نمیشود!")
# رفتار تابع وقتی ورودی string است
@process.register(str)
def _(data):
return f"متن: {data.strip().upper()}"
# رفتار تابع وقتی ورودی int است
@process.register(int)
def _(data):
return f"عدد: {data * 10}"
# رفتار تابع وقتی ورودی list است
@process.register(list)
def _(data):
return f"تعداد عناصر لیست: {len(data)}"
# 🧪 تست:
print(process(" python ")) # خروجی: متن: PYTHON
print(process(5)) # خروجی: عدد: 50
print(process([1, 2, 3])) # خروجی: تعداد عناصر لیست: 3
🔹به چه دردی میخوره؟
کدت کاملاً تمیز، ماژولار و بر اساس اصل Open/Closed در SOLID میشه. هر زمان نوع داده جدیدی اضافه شد، کافیه یک تابع جدید @register کنی بدون اینکه کد قبلی رو دستکاری کنی!
🐍 @python_rd4 106
🔆 تست پایتون: خروجی این کد چی میشه؟
data = [1, 2, 3]
result = [lambda x: x * i for i in data]
print([f(2) for f in result])
🔹گزینهها:
۱) [2, 4, 6]
۲) [6, 6, 6]
۳) [1, 2, 3]
۴) Error
🐍 @python_rd4 106
🔆 قدرت List Comprehension در پایتون
🔹 به جای نوشتن چندین خط کد برای ساختن یک لیست جدید، میتونی کل عملیات رو در یک خط انجام بدی. این کار هم کدت رو خواناتر میکنه و هم از نظر سرعت اجرا بهینهتره."
🔹روش سنتی و طولانی:
numbers = [1, 2, 3, 4, 5, 6]
even_squares = []
for n in numbers:
if n % 2 == 0:
even_squares.append(n**2)
print(even_squares) # [4, 16, 36]
🔹روش حرفهای بهتر:
numbers = [1, 2, 3, 4, 5, 6]
even_squares = [n**2 for n in numbers if n % 2 == 0]
print(even_squares) # [4, 16, 36]
🔹نکته: اگر شرطها خیلی پیچیده شدن، از همون روش for معمولی استفاده کن تا خوانایی کد از دست نره.
🔹 به چه دردی میخوره؟
کد کوتاهتر، سرعت بیشتر و ظاهر حرفهایتر.
🐍 @python_rd4 106
🔆 حذف آیتمهای تکراری از لیست، بدون بههمریختن ترتیب
🔹 فرض کن از API یه لیست دریافت کردی:
users = ["ali", "reza", "sara", "ali", "mohammad", "reza"]
میخوایم آیتمهای تکراری حذف شن، اما ترتیب اصلی لیست حفظ بشه.
🔹 خب میگی اینکارو میکنم:
unique_users = list(set(users))
print(unique_users)
🔹 ولی مشکل اینجاست که set ترتیب آیتمها رو تضمین نمیکنه.
🔹راه بهتر:
users = ["ali", "reza", "sara", "ali", "mohammad", "reza"]
unique_users = list(dict.fromkeys(users))
print(unique_users)
🔹خروجی:
['ali', 'reza', 'sara', 'mohammad']
🔹چرا کار میکنه؟
دیکشنری تو پایتون کلید تکراری قبول نمیکنه و ترتیب اضافهشدن کلیدها رو هم نگه میداره.
پس dict.fromkeys() آیتمهای تکراری رو حذف میکنه و ترتیب لیست رو هم حفظ میکنه.
🔹این تکنیک برای تمیز کردن دادههای دریافتی از فرم، API، فایل CSV و دیتابیس به درد میخوره.
🐍 @python_rd