Syntax | سینتکس
3.02K subscribers
410 photos
108 videos
35 files
377 links
Download Telegram
Syntax | سینتکس
استفاده از الگوی طراحی Singleton در پایتون: class SingletonMeta(type): """ The Singleton class can be implemented in different ways in Python. Some possible methods include: base class, decorator, metaclass. We will use the metaclass because…
یه نکته در خصوص الگوی singleton در پایتون بگم:

استفاده از singleton تو پایتون یکی از bad practice ها به حساب میاد.
بجاش پیشنهاد میشه از قابلیت function cache استفاده کنیم.

مثلا:
@functools.cache
def the_chess_board():
return ChessBoard()
اگه هنوزم میخواید با کلاس single instance رو مدیریت کنید از این روش استفاده کنید:

class ChessBoard:
def __init__(self):
...

@classmethod
@functools.cache
def the_board(cls):
return cls()
لینک مقاله:
https://nedbatchelder.com/blog/202204/singleton_is_a_bad_idea.html

#singleton #python

@Syntax_fa
👍4
پراکندگی موقعیت شغلی بک اند پایتون

هر چی تیره تر یعنی بیشتره

منبع:
https://workhunty.com/job-blog/where-is-the-best-place-to-be-a-programmer/Django/

#python

@Syntax_fa
👍12🤣4🔥1
How to use annotations in python.pdf
699.1 KB
نحوه استفاده از Annotations در پایتون

خوب خیلی ها اسم annotations به گوششون نخورده و یا اینکه مستقیما باهاش درگیر نشدن بلکه بیشتر جا ها دیدن ولی پاکش کردن! مثل اوایل کار من.
واقعیت اینه که اگر یه تعریف ساده ازش بخوام بکنم ،Annotation در واقع meta-data ای هستش که شما به بخش های کد اضافه میکنید تا خطایابی و درک کد بهتر بشه.
اما مدل های مختلفی از annotation ها رو ممکنه ببینید که یکسری روی متغیر ها، کلاس ، توابع ، ورودی و خروجی ها ، توضیحات کلی و ... قرار میگیرن.
همچنین در زمان ایجاد داکیومنتری هم خیلی کاربرد داره و بیش از پیش استفاده میشه.
معمولا از زمانی که شما با روابط شئ گرایی درگیر میشید شروع بهش شناخت annotation ها و موارد استفاده اون می کنین.

از انواع اون میشه به موارد زیر اشاره کرد:

- Type Annotations
- Custom Metadata Annoations
- Parameter Annotations
- Module Annotations
- Attribute Annotations
- Return Annotations

link

#python #annotation

@Syntax_fa | @Syntax_fa_group
👍5
سوال پایتونی:
در مورد مفهوم Context Managers در Python توضیح دهید. چگونه می‌توان یک Context Manager سفارشی ایجاد کرد؟ یک مثال عملی ارائه دهید.

Context Managers
در Python ابزارهایی برای مدیریت منابع (مانند فایل‌ها، قفل‌ها و اتصالات پایگاه داده) هستند. آن‌ها اطمینان حاصل می‌کنند که منابع به درستی آزاد شوند، حتی در صورت رخ دادن خطا یا استثنا.

برای ایجاد یک Context Manager سفارشی، شما باید یک کلاس ایجاد کنید که دو متد __enter__ و __exit__ را پیاده‌سازی می‌کند. متد __enter__ باید منبع را آماده کند و آن را برگرداند. متد __exit__ باید منبع را آزاد کند و با استثناهای رخ داده به درستی برخورد کند.

مثال عملی: فرض کنید می‌خواهیم یک Context Manager برای باز کردن و بستن فایل‌ها بنویسیم:

class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode

def __enter__(self):
self.file = open(self.filename, self.mode)
return self.file

def __exit__(self, exc_type, exc_value, traceback):
self.file.close()

with FileManager('data.txt', 'w') as f:
f.write('Hello, World!')


در این مثال، FileManager یک کلاس Context Manager است. متد __enter__ فایل را باز می‌کند و شیء فایل را برمی‌گرداند. متد __exit__ فایل را می‌بندد، حتی اگر استثنایی در بلوک with رخ دهد.

#python #context_manager

@Syntax_fa
👍5🔥1
زمان و حافظه خود را با list comprehension، map و generator نجات دهید!
سلام رفقا!

سطح = مقدماتی

امروز می خواهم به شما 3 ابزار قدرتمند در پایتون را معرفی کنم که می توانند به شما در صرفه جویی در زمان و حافظه هنگام کار با لیست ها و داده ها کمک کنند:

1. list comprehension:

این ابزار به شما امکان می دهد لیست های جدیدی را با کدی کوتاه و خوانا از لیست های موجود بسازید.

به جای استفاده از for loop های سنتی، می توانید از list comprehension برای فیلتر کردن، نگاشت و تغییر عناصر لیست به طور همزمان استفاده کنید.

مثال:
numbers = [1, 2, 3, 4, 5]
squared_numbers = [n * n for n in numbers]
print(squared_numbers) # Output: [1, 4, 9, 16, 25]

بااحتیاط از کد استفاده کنید.
2. map:

این تابع به شما امکان می دهد یک عملکرد را به هر عنصر لیست اعمال کنید و نتیجه را به عنوان یک لیست جدید برگردانید.

map برای تغییر یا نگاشت داده ها در یک لیست به طور یکسان مفید است.

مثال:
def double(x):
return x * 2

numbers = [1, 2, 3, 4, 5]
doubled_numbers = list(map(double, numbers))
print(doubled_numbers) # Output: [2, 4, 6, 8, 10]

بااحتیاط از کد استفاده کنید.
3. generator:

ژنراتورها به شما امکان می دهند به طور متوالی مقادیر را از یک مجموعه داده تولید کنید بدون اینکه کل مجموعه داده را به یکباره در حافظه نگه دارید.

این امر آنها را برای کار با مجموعه داده های بزرگ که ممکن است در حافظه شما جا نشوند، ایده آل می کند.

مثال:
def even_numbers(start, end):
for n in range(start, end + 1):
if n % 2 == 0:
yield n

for even_number in even_numbers(1, 20):
print(even_number) # Output: 2 4 6 8 10 12 14 16 18 20

بااحتیاط از کد استفاده کنید.
با استفاده از این 3 ابزار قدرتمند، می توانید کد خود را کارآمدتر و مختصرتر کنید و در عین حال از حافظه و زمان خود به طور موثرتر استفاده کنید.

درضمن یه نکته رو خودم اضافه کنم که استفاده از list comprehension و map
نسبت به حلقه‌های for معمولی در پایتون ، ۲ الی ۳ برابر در زمان و حافظه صرفه جویی می‌کنه!
منبع:
Learn web development with python

[amirhossein]

#python

@Syntax_fa
👍11🔥3😁1
سوال پایتونی:
1. توضیح دهید که چگونه می‌توان از decorators در Python استفاده کرد. یک مثال عملی از کاربرد decorators ارائه دهید.

پاسخ: Decorators در Python یک الگوریتم قدرتمند برای تغییر رفتار تابع‌ها یا کلاس‌ها در زمان اجرا هستند. آن‌ها به شما امکان می‌دهند تا کدهای قابل استفاده مجدد بنویسید و از طریق (Wrapper) تابع‌ها را گسترش دهید. برای استفاده از آن‌ها، شما یک تابع دیگر را تعریف می‌کنید که تابع اصلی را در برمی‌گیرد و کدهای اضافی قبل یا بعد از اجرای تابع اصلی اضافه می‌کند.

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

import time

def log_execution_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"Function {func.__name__} took {end_time - start_time} seconds to execute.")
return result
return wrapper

@log_execution_time
def my_function(n):
result = 0
for i in range(n):
result += i
return result

my_function(10000000)


در این مثال، log_execution_time یک decorator است که یک تابع دیگر را می‌پذیرد (در اینجا my_function) و یک تابع جدید با نام wrapper را برمی‌گرداند که تابع اصلی را فرا می‌خواند و زمان اجرای آن را لاگ می‌کند.

#python #decorators

@Syntax_fa
👍11🔥21
سوال پایتونی:

چگونه می‌توان در Python از ویژگی‌های Dataclasses برای ایجاد کلاس‌های ساده‌تر و قابل مدیریت‌تر استفاده کرد؟ یک مثال ارائه دهید.

Dataclasses
در Python یک راه ساده برای تعریف کلاس‌های حاوی داده‌ها (data classes) فراهم می‌کنند. این ویژگی در Python 3.7 معرفی شد و از کد تکراری برای تعریف متدهای init، repr، eq و دیگر متدهای پایه‌ای جلوگیری می‌کند.

برای استفاده از Dataclasses، کافی است از دکوراتور @dataclass روی تعریف کلاس استفاده کنید. سپس می‌توانید فیلدهای کلاس را با انواع داده مختلف تعریف کنید.

مثال:

from dataclasses import dataclass

@dataclass
class Person:
    name: str
    age: int
    email: str = None

person1 = Person("Alice", 30, "alice@example.com")
person2 = Person("Bob", 25)

print(person1)  # Output: Person(name='Alice', age=30, email='alice@example.com')
print(person2)  # Output: Person(name='Bob', age=25, email=None)

print(person1 == person2)  # Output: False


در این مثال، Person یک dataclass است که سه فیلد name، age و email دارد. فیلد email یک مقدار پیش‌فرض None دارد. با استفاده از @dataclass، Python به طور خودکار متدهایی مانند init و repr را برای ما ایجاد می‌کند.

Dataclasses همچنین امکانات دیگری مانند مقایسه اشیاء، هش‌پذیری، و گزینه‌های پیشرفته‌تر را نیز فراهم می‌کنند.

#python

@Syntax_fa
👍121
Lambda Expression

توضیح: Lambda expressions، که به عنوان anonymous functions (توابع بی‌نام) نیز شناخته می‌شوند، توابعی هستند که بدون نام تعریف می‌شوند و برای عملیات‌های کوچک و ساده مورد استفاده قرار می‌گیرند. در پایتون، این توابع با استفاده از کلمه کلیدی lambda تعریف می‌شوند.

کار با Lambda Expression در پایتون

lambda arguments: expression


- arguments: آرگومان‌هایی که تابع می‌پذیرد.
- expression: عبارتی که ارزیابی می‌شود و نتیجه آن برگردانده می‌شود.

مثال ساده

در این مثال، یک تابع لامبدا تعریف می‌کنیم که دو عدد را با هم جمع می‌کند:

add = lambda x, y: x + y

result = add(3, 4)
print(result) # Output: 7


در اینجا، تابع لامبدا دو آرگومان x و y می‌پذیرد و مقدار x + y را برمی‌گرداند.

استفاده از Lambda Expressions در توابع higher-order

توابع higher-order توابعی هستند که یک یا چند تابع را به عنوان آرگومان می‌پذیرند و یا تابعی را برمی‌گردانند. Lambda expressions معمولاً در توابع higher-order مانند map(), filter(), و reduce() استفاده می‌شوند.

مثال با map()

تابع map() یک تابع را روی هر آیتم از یک iterable اعمال می‌کند:

numbers = [1, 2, 3, 4, 5]

doubled = map(lambda x: x * 2, numbers)

print(list(doubled)) # Output: [2, 4, 6, 8, 10]


مثال با filter()

تابع filter() آیتم‌هایی را که تابع به عنوان True ارزیابی می‌کند، فیلتر می‌کند:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

evens = filter(lambda x: x % 2 == 0, numbers)

print(list(evens)) # Output: [2, 4, 6, 8, 10]


مثال با reduce()

تابع reduce() از ماژول functools (توضیح اینکه دقیقا چطور عمل میکنه رو خواستید بگید تو یه پست دیگه بگم):

from functools import reduce

numbers = [1, 2, 3, 4, 5]

product = reduce(lambda x, y: x * y, numbers)

print(product) # Output: 120


#lambda_expression #python #filter #map #reduce

@Syntax_fa
👍6
Syntax | سینتکس
bytes buffer and string builder یکی از انواع داده ای که در اکثر زبان‌های برنامه نویسی وجود دارد و در استفاده از آن باید دقت داشته باشیم نوع string است. قطعه کد زیر را در نظر بگیرید: var query string = "select " query += "name, family " query…
سوال:
تو پایتون چطور از string builder استفاده کنیم؟

جواب:
تو سایت real python یه مقاله خوب راجب اینکه چطور بصورت بهینه با رشته ها کار کنیم هست یکی از مثال هایی که زده اینه:
from io import StringIO

sentence = StringIO()
while True:
word = input("Enter a word (or './!/?' to end the sentence): ")
if word in ".!?":
sentence.write(word)
break
if sentence.tell() == 0:
sentence.write(word)
else:
sentence.write(" " + word)

print("The concatenated sentence is:", sentence.getvalue())


لینک:
https://realpython.com/python-string-concatenation/

#python #string_builder

@Syntax_fa
🔥7👍1🙏1
پکیج `python-decouple`

یک ابزار مفید برای جداسازی تنظیمات و پیکربندی‌های پروژه‌های پایتون است. این کار باعث می‌شود که کد شما از وابستگی‌های محیطی جدا باشد و تنظیمات را به راحتی تغییر دهید بدون اینکه نیاز به تغییر در کد داشته باشید. این پکیج به خصوص برای مدیریت متغیرهای محیطی و تنظیمات حساس مانند کلیدهای API، اطلاعات پایگاه داده و غیره بسیار مفید است.

ویژگی‌ها
- مدیریت متغیرهای محیطی: متغیرهای محیطی را از فایل .env بارگذاری می‌کند.
- پشتیبانی از انواع داده‌ها: قابلیت تبدیل مقادیر متغیرها به انواع داده‌ای مختلف مانند int`، `float`، `bool و ...
- مقدار پیش‌فرض: امکان تعریف مقادیر پیش‌فرض برای متغیرهایی که ممکن است در محیط تنظیم نشده باشند.

نصب

برای نصب پکیج python-decouple می‌توانید از دستور زیر استفاده کنید:
pip install python-decouple


نحوه استفاده

1. ایجاد فایل `.env`:
ابتدا یک فایل با نام .env در ریشه پروژه خود ایجاد کنید و تنظیمات مورد نظر خود را در آن وارد کنید. برای مثال:

   DEBUG=True
SECRET_KEY=mysecretkey
DATABASE_URL=postgres://user:password@localhost:5432/mydatabase


2. استفاده از `config` در کد پایتون:
در کد پایتون خود، پکیج decouple را وارد کرده و از Config استفاده کنید:

   from decouple import config

DEBUG = config('DEBUG', default=False, cast=bool)
SECRET_KEY = config('SECRET_KEY')
DATABASE_URL = config('DATABASE_URL')


3. توضیحات بیشتر:
- config('DEBUG', default=False, cast=bool):
این خط مقدار متغیر DEBUG را از فایل .env می‌خواند و آن را به نوع bool تبدیل می‌کند. اگر این متغیر در فایل .env موجود نباشد، مقدار پیش‌فرض False استفاده می‌شود.
- config('SECRET_KEY'):
این خط مقدار متغیر SECRET_KEY را از فایل .env می‌خواند.
- config('DATABASE_URL'):
این خط مقدار متغیر DATABASE_URL را از فایل .env می‌خواند.

مثال کامل

فرض کنید یک پروژه ساده دارید که از Flask استفاده می‌کند و می‌خواهید تنظیمات خود را با استفاده از python-decouple مدیریت کنید.

1. ایجاد فایل `.env`:

   DEBUG=True
SECRET_KEY=mysecretkey
DATABASE_URL=sqlite:///mydatabase.db


2. کد پایتون:

   from flask import Flask
from decouple import config

app = Flask(__name__)

app.config['DEBUG'] = config('DEBUG', default=False, cast=bool)
app.config['SECRET_KEY'] = config('SECRET_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = config('DATABASE_URL')

@app.route('/')
def home():
return "Hello, World!"

if __name__ == '__main__':
app.run()


این کد یک برنامه ساده Flask ایجاد می‌کند که تنظیمات خود را از فایل .env می‌خواند. با این کار، می‌توانید به راحتی تنظیمات خود را تغییر دهید بدون اینکه نیاز به تغییر در کد داشته باشید.

#python_decouple

@Syntax_fa
👍3🔥21👌1
از پایتون 3.13 چخبر؟ 🍸

1. یک مفسر تعاملی (Interactive Interpreter) بهتر

پایتون 3.13 بهبودهای قابل توجهی در مفسر تعاملی به همراه پیام‌های خطای پیشرفته معرفی می‌کند. مفسر تعاملی جدید اکنون از رنگ‌بندی پشتیبانی می‌کند و تجربه‌ای بصری‌تر ارائه می‌دهد. این پشتیبانی از رنگ به tracebacks و خروجی doctest نیز گسترش می‌یابد. کاربران می‌توانند رنگ‌بندی را از طریق متغیرهای محیطی PYTHON_COLORS و NO_COLOR غیرفعال کنند.

علاوه بر این، پایتون 3.12 شامل یک کامپایلر JIT (Just-In-Time) اولیه بر اساس PEP 744 است. اگرچه در حال حاضر به‌طور پیش‌فرض غیرفعال است، این کامپایلر نشان‌دهنده بهبودهای عملکردی امیدوارکننده‌ای است و برنامه‌هایی برای بهبودهای بیشتر در نسخه‌های بعدی وجود دارد.

2. کامپایل آزمایشی Just-in-Time (JIT)


پایتون یک کامپایلر آزمایشی just-in-time (JIT) معرفی می‌کند که در صورت فعال‌سازی، می‌تواند برخی برنامه‌های پایتون را سریع‌تر کند. کامپایلر JIT با ترجمه bytecode تخصصی Tier 1 به یک نمایش میانی داخلی Tier 2 جدید کار می‌کند که برای ترجمه به کد ماشین بهینه شده است. چندین مرحله بهینه‌سازی به Tier 2 IR اعمال می‌شود قبل از اینکه تفسیر یا به کد ماشین ترجمه شود. گزینه‌های پیکربندی (–enable-experimental-jit) به کاربران اجازه می‌دهد تا رفتار JIT را در زمان ساخت و اجرا کنترل کنند، از جمله فعال یا غیرفعال کردن JIT و مفسر Tier

مزایای بالقوه کامپایلر JIT:
بهبود عملکرد قابل توجه برای بخش‌های خاصی از کد که از اجرای کد ماشین سود می‌برند.
امکان بهینه‌سازی‌های آینده که قبلاً با تفسیر bytecode ممکن نبودند.

3. سی پایتون (CPython) آزمایشی بدون GIL

سی پایتون اکنون از اجرای بدون Global Interpreter Lock (GIL) پشتیبانی می‌کند، که امکان اجرای multithreadding آزاد را با پیکربندی –disable-gil فراهم می‌سازد. اجرای چندریسمانی آزاد به بهره‌برداری بهتر از هسته‌های CPU موجود از طریق اجرای موازی ریسمان‌ها کمک می‌کند و به برنامه‌هایی که برای threading طراحی شده‌اند، سود می‌رساند.
ماژول‌های توسعه C-API باید به‌طور خاص برای ساختار چندریسمانی آزاد ساخته شوند و باید با استفاده از مکانیزم‌های مناسب، پشتیبانی از اجرای بدون GIL را نشان دهند.

4. گزارش‌دهی و راهنمایی خطای بهبود یافته

ردیابی خطا در پایتون در نسخه جدید بهبود یافته است. مفسر اکنون پیام‌های خطا را به‌طور پیش‌فرض هنگام نمایش tracebacks رنگی می‌کند. در ویژگی دیگر، پیام خطا در صورت ارسال یک کلیدواژه اشتباه به یک تابع، کلیدواژه صحیح را پیشنهاد می‌دهد.

گاهی اوقات که یک اسکریپت همنام یک ماژول کتابخانه استاندارد است، پایتون اکنون پیام خطای دقیقی ارائه می‌دهد و پیشنهاد می‌کند برای درک بهتر، نام ماژول تغییر کند.
>>> sys.version_info
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined. Did you forget to import 'sys'!

5. جمع‌آوری زباله افزایشی

پایتون 3.12 جمع‌آوری زباله افزایشی را معرفی می‌کند که زمان توقف حداکثر را برای هیپ‌های بزرگتر به طور قابل توجهی کاهش می‌دهد. این بهبود به‌ویژه برای برنامه‌هایی با تخصیص و آزادسازی حافظه زیاد مفید است.
# Python 3.12
import gc
gc.isincremental()  # Returns True

این ویژگی به برنامه‌های پایتون اجازه می‌دهد تا روان‌تر اجرا شوند و تأثیر توقف‌های جمع‌آوری زباله کاهش یابد، که به بهبود عملکرد کلی و واکنش‌پذیری منجر می‌شود.

6. بهینه‌سازی حافظه برای Docstrings


پایتون 3.13 تغییری ظریف اما مؤثر برای بهبود کارایی حافظه معرفی می‌کند: بهینه‌سازی حافظه برای Docstrings. این ویژگی منبع پنهانی از استفاده حافظه و اندازه فایل مرتبط با docstrings در کد پایتون را هدف قرار می‌دهد.

محدودیت‌های Docstrings سنتی در پایتون به شرح زیر است:
به‌طور سنتی، docstrings در پایتون شامل هر گونه فاصله تورفتگی ابتدایی بودند. در حالی که این فضاهای اضافی به نظر بی‌ضرر می‌آیند، به اندازه کلی فایل‌های bytecode کامپایل‌شده (.pyc) افزوده و احتمالاً استفاده از حافظه را هنگام اجرای کد افزایش می‌دادند.

مزایای بهینه‌سازی حافظه برای Docstrings:
بهینه‌سازی حافظه برای Docstrings این ناکارآمدی را برطرف می‌کند. به‌طور خودکار هر گونه تورفتگی ابتدایی را از docstrings قبل از فرآیند کامپایل حذف می‌کند.
این اطمینان می‌دهد که تنها محتوای واقعی docstring ذخیره می‌شود، که منجر به:
کاهش استفاده از حافظه برای فایل‌های bytecode کامپایل‌شده.
احتمالاً کاهش استفاده از حافظه در هنگام اجرای برنامه، به‌ویژه برای پروژه‌هایی با docstring گسترده.

Source

#python

@Syntax_fa
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥13💋3👍21🥰1
تو چند دقیقه نحوه کار با Redis Pub/Sub رو تو پایتون یاد بگیر

Pub/Sub
(انتشار/اشتراک) یک الگوی معماری است که به برنامه‌ها اجازه می‌دهد تا به صورت غیرمستقیم با یکدیگر ارتباط برقرار کنند. در این الگو، تولیدکنندگان اطلاعات (Publisher) پیام‌ها را منتشر می‌کنند و مصرف‌کنندگان (Subscriber) به موضوعات (Topics) خاصی که به آن‌ها علاقه‌مند هستند، اشتراک می‌گذارند. این سیستم اجازه می‌دهد تا بدون نیاز به وابستگی مستقیم با یکدیگر، اطلاعات را تبادل کنند.

مزایای Pub/Sub
- کاهش وابستگی‌ها: تولیدکنندگان و مصرف‌کنندگان نیازی به شناخت یکدیگر ندارند.
- مقیاس‌پذیری: می‌توان به سادگی مصرف‌کنندگان و تولیدکنندگان جدیدی اضافه کرد.
- توزیع‌پذیری: می‌توان سیستم‌ها را به صورت توزیع‌شده پیاده‌سازی کرد.

مثال ساده با Redis Pub/Sub


در این مثال، از Redis به عنوان سیستم Pub/Sub استفاده خواهیم کرد. ابتدا باید Redis را نصب و راه‌اندازی کنید.

نصب Redis

تو ریپازیتوری ای که لینکشو آخر پست میذارم، سرویس ردیس رو توی docker-compose.yml مشخص کردم و روی داکر اجراش میکنیم.
همچنین داخل فایل .env تنظیمات ردیس رو میتونید مشخص کنید.

docker-compose up -d


پیاده‌سازی در پایتون

برای این کار به کتابخانه redis نیاز داریم. می‌توانید آن را با pip نصب کنید:

pip install redis



در این مثال، یک Publisher و یک Subscriber خواهیم داشت.

Publisher (server.py):

import json

from redis import StrictRedis


server = StrictRedis(host="localhost", port=6399, password="redis_password", db=0)

# redis ping
print(server.ping())

topic = "example_topic"

data = {
"name": "alireza",
"age": 22,
}

server.publish(channel=topic, message=json.dumps(data))


در قدم اول کانکشن با ردیس رو می سازیم.
با متد ping میتونیم چک کنیم وضعیت کانگشنمون اوکی هست یا نه(جنبه آموزشی نوشتمش)
بعد مشخص کردیم که topic ما اسمش چیه.
دیتایی که قراره داخل payload مسیج قرار بدیم رو مشخص کردیم که بصورت دیکشنری هستش و بعدش اومدیم به json تبدیلش کردیم و مسیح رو پابلیش کردیم.

Subscriber (client.py):

import json

from redis import StrictRedis


client = StrictRedis(host="localhost", port=6399, password="redis_password", db=0)

topic = "example_topic"

pubsub = client.pubsub()

pubsub.subscribe(topic)

print("waiting for message...")

while True:
for message in pubsub.listen():
if message["data"] == 1:
continue
match message["type"]:
case topic:
# TODO - change serialization. json is not good
data = json.loads(message["data"])
print("received message", data["name"], data["age"])

در قدم اول یک کانکشن ردیس گرفتیم. بعد تاپیکی که subscribe میکنیمش رو مشخص کردیم(میتونیم چندین تا تاپیک رو سابسکرایب کنیم)
در قدم بعدی داخل یک long running میایم به مسیج های جدیدی که میاد گوش میدیم و یک switch case زدیم و براساس تاپیک ها میتونیم کارهای خاص خودش رو انجام بدیم.

نحوه اجرا

1. در یک ترمینال، client.py را اجرا کنید
2. در یک ترمینال دیگه server.py رو اجرا کنید که با هربار اجرا یک مسیج رو پابلیش میکنه.

سورس کد:
https://github.com/alireza-fa/redis-pub-sub-example

#redis_pub_sub #pub_sub #event_driven #python

@Syntax_fa
🔥6💋4👍31👎1🙏1
Syntax | سینتکس
ساخت یک Dockerfile مناسب برای پروژه های پایتونی: خیلی خوب توضیح داده. https://luis-sena.medium.com/creating-the-perfect-python-dockerfile-51bdec41f1c8 #python #Dockerfile @Syntax_fa
و اما Docekrfile که من از توضیحات ایشون رسیدم بهش:
FROM python:3.11-slim as builder

# avoid stuck build due to user prompt
ARG DEBIAN_FRONTEND=noninteractive

RUN apt-get update && \
apt-get install -y --no-install-recommends ...

# create and activate virtual environment
RUN python -m venv /home/myuser/venv
ENV PATH="/home/myuser/venv/bin:$PATH"

# install requirements
COPY ./requirements .
RUN pip3 install --upgrade --no-cache-dir pip
RUN pip3 install --no-cache-dir wheel
RUN pip3 install --no-cache-dir -r production.txt

FROM python:3.11-slim

RUN useradd --create-home myuser
COPY --from=builder /home/myuser/venv /home/myuser/venv

USER myuser
RUN mkdir /home/myuser/code
WORKDIR /home/myuser/code
COPY . /home/myuser/code

EXPOSE $DJANGO_PORT

# make sure all messages always reach console
ENV PYTHONUNBUFFERED=1

# activate virtual environment
ENV VIRTUAL_ENV=/home/myuser/venv
ENV PATH="/home/myuser/venv/bin:$PATH"

# /dev/shm is mapped to shared memory and should be used for gunicorn heartbeat
# this will improve performance and avoid random freezes
# CMD ["gunicorn","-b", "0.0.0.0:8000", "-w", "4", "-k", "gevent", "--worker-tmp-dir", "/dev/shm", "--chdir", "config config.wsgi:application"]


نظر بدید

#python #dockerfile

@Syntax_fa
🔥6👍1🤣1🤨1
ارور ثروتمند و یا RichError 😏

ریچ ارور یک الگوی مدیریت خطا در برنامه‌نویسی است که به شما این امکان رو می‌ده تا اطلاعات دقیق‌تری درباره خطاها ها و لایه های مختلفی که این خطا رخ داده تا در نهایت به دست شما رسیده ذخیره کنید و بر اساس این اطلاعات جمع آوری شده، به کاربر یا سیستم‌های دیگه ارور و پیغام مناسب رو به راحتی نمایش بدید.

بر خلاف خطاهای استاندارد که معمولاً فقط شامل یک پیام یا کد خطا هستند، RichError میتونه شامل اطلاعات اضافی مثل متا دیتا، اپریشنی که توش خطا رخ داده، ارور های لایه پایین تر و هر اطلاعاتی که بدردتون میخوره رو داشته باشید.

چرا بهش Rich error میگیم؟

1. اطلاعات بیشتر:
- ریچ ارور میتونه شامل پیام خطا، کد خطا، نام عملی که باعث خطا شده و هر نوع اطلاعات دیگه باشه. این اطلاعات میتونن شامل متا دیتاهایی باشن که به درک بهتر مشکل کمک میکنن(خیلی کمک میکنن).

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

3. خیلی کارتونو راحت تر میکنه:
- تو مثال هایی که براتون زدم میفهمید که چقدر کارتون رو ساده تر میکنه همچنین باعث میشه کدتون منظم تر و یکپارچه بشه.

اگه هنوز درباره استفاده از Rich error دودلی اینم چند مزایای دیگه:

1. تشخیص بهتر مشکلات:
- با داشتن اطلاعات غنی درباره خطاها، تیم‌های توسعه میتونن سریع‌تر و دقیق‌تر مشکلات رو شناسایی و حل کنن.

2. تجربه کاربری بهبود یافته:
- وقتی که خطاها به صورت واضح و با اطلاعات کافی به کاربر نمایش داده بشه، تجربه کاربری خیلی بهتر میشه.

3. توسعه سریع‌تر:
- با استفاده از RichError، سرعت توسعتون بیشتر میشه(طبق تجربه خودم)

5. سازگاری با سیستم‌های دیگه:
- اطلاعات کافی و ساختارمند ریچ ارور میتونه به راحتی به سیستم‌های دیگر منتقل بشه مثلا میتونید توی لاگرتون هم از اطلاعات ریچ ارور استفاده کنید.

چطور یک ریچ ارور خوب بنویسیم؟

تو ریپازیتوری زیر من ریچ اروری که تقریبا خودم استفاده میکنم رو قرار دادم. همچنین بخوبی درباره rich error توضیح دادم که اگه دوست دارید خودتون بنویسید چه مواردی رو باید رعایت کنید.
https://github.com/alireza-fa/rich-error
برای نصب:
pip install rich-error

ستاره فراموش نشه❤️

#rich_error #python

@Syntax_fa
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6🔥5👌3
Syntax | سینتکس
ارور ثروتمند و یا RichError 😏 ریچ ارور یک الگوی مدیریت خطا در برنامه‌نویسی است که به شما این امکان رو می‌ده تا اطلاعات دقیق‌تری درباره خطاها ها و لایه های مختلفی که این خطا رخ داده تا در نهایت به دست شما رسیده ذخیره کنید و بر اساس این اطلاعات جمع آوری شده،…
برای آشنایی بیشتر یه مثال هم اضافه کنم:

اگر از rich error استفاده نکنیم، برای هندل کردن ارور های مختلف مجبور بودیم از یک سولوشن دیگه بجز exception استفاده کنیم و یا اینکه بیایم و برای هر ارور به این صورت exceptionبنویسیم:
class UserNotFoundErr(Exception):
    pass


class IpBlockedErr(Exception):
    pass


class TooManyRequestErr(Exception):
    pass


class UserConflictErr(Exception):
    pass

در handler هم باید این کار رو میکردیم:

from examples.without_rich_error.service import get_user_service
from examples.without_rich_error.exception import UserNotFoundErr, UserConflictErr, TooManyRequestErr, IpBlockedErr


def get_user_handler(user_id: int):
    try:
        print(service.get_user_by_id(user_id=user_id))
    except UserNotFoundErr as err:
        print("user not found code is 404", err)
    except UserConflictErr as err:
        print("user conflict code is 409", err)
    except TooManyRequestErr as err:
        print("too many request code is 429", err)
    except IpBlockedErr as err:
        print("ip blocked code is 403", err)

در این صورت هرچقدر تعداد exceptionها بیشتر شود مدیریت کردن آنها نیز سخت تر خواهد شد. همچنین قدرت مشاهده گری سیستم با استفاده از exception ها نیز پایین می آید در صورتی که ما در rich error تمامی ارور هایی که در لایه های مختلف رخ داده باشند رو داشتیم.

اگه کد رو با rich error جایگزین کنیم:

from examples.with_rich_error.api import base_response_with_error, base_response


def get_user_handler(user_id: int):
    try:
        ...
    except Exception as err:
        return base_response_with_error(error=err)

از آنجا که ما یک ارور غنی داریم و از کد ها استفاده کردیم به راحتی میدانیم که این ارور به چه معنی است و حتی به سادگی http error مناسب را برگردانیم.

#rich_error #python

@Syntax_fa
👍8🔥5👏1
نکات مهم اجرای جنگو با Gunicorn

توضیح درباره Gunicorn
نمیخوام توضیحات زیادی بدم حوصلتون سر بره پس همون سه خط معرفی که تو وب سایت gunicorn نوشته رو براتون یکم شفافش میکنم:
اسمش مخفف green unicorn هستش
جی یونیکورن یک http سرور هستش که از استاندارد WSGI(Web server gateway interface) برای اجرای برنامه های وب پایتون استفاده میکنه.
استاندارد WSGI برای این بوجود اومد تا هر فریم ورک وب پایتونی روش خودشو واسه ارتباط پیاده نکنه و همه از یه استاندارد مشخص استفاده کنن.

در ادامه میگه gunicorn برای unix هستش و برای سیستم عامل هایی مثل مک و لینوکس طراحی شده.

بعدش میگه که جی یونیکورن از مدل pre-fork worker استفاده میکنه حالا این به چه معنیه؟
جی یونیکورن کاری که میکنه اینه قبل اینکه شروع به پردازش درخواست ها کنه، میاد و به اندازه ای که تنظیم کردید worker ایجاد میکنه که هر worker درخواست هارو بطور مستقل پردازش میکنه.

بعدشم میگه با فریم ورک های وب مختلفی سازگاره که اینم میتونیم دلیلش رو این بدونیم داره برای ارتباط از استاندارد WSGI استفاده میکنه.

قسمت آخرشم میگه light resource هستش و منابع کمی مصرف میکنه همچنین برای ترافیک بالا عملکرد خوبی داره.

خب جی یونیکورن این ادعا هارو میکنه اما بیاید با چند تا مثال شرایطی رو بررسی کنیم که شما به غلط دارید از جی یونیکورن استفاده میکنید:

مثال اول
gunicorn --chdir config config.wsgi:application -b 0.0.0.0:8000

اگه با این دستور جی یونیکورن رو اجرا کنید باید به این نکته دقت کنید بصورت پیشفرض براتون فقط یدونه worker میسازه که این اصلا خوب نیست. خود جی یونیکورن پیشنهاد میده حتی اگه یدونه core دارید 4 تا ورکر بسازید و یه فرمولی هم داده که میگه«تعداد هسته های سی پی یو رو ضربدر 2 به علاوه یک کنید»
همچنین به شما اطمینان داده همین تعداد ورکر هزاران ریکوئست رو میتونن پاسخ بدن پس تعداد ورکر هارو الکی زیادش نکنید.
البته به کیس شما هم بستگی داره.
دستور بهتر برای اجرا اینه تعداد ورکر هارو مشخص کنیم:
gunicorn --workers 5 --chdir config config.wsgi:application -b 0.0.0.0:8000


مثال دوم:
فرض کنید کاربر ها تو اپلیکیشن شما فایل هایی رو آپلود میکنن. شما پنج تا ورکر دارید.
وقتی پنج تا کاربر همزمان فایل آپلود کنن بنظرتون چه اتفاقی میوفته؟
پنج تا ورکر شما گیر یه io افتادن و مشغولن و درخواست های دیگه کاربرا انجام نمیشه. خب این وضعیتی نیست که باب میلیتون باشه!
برای حل این مشکل کافیه از gevent توی جی یونیکرون استفاده گنید؛
gunicorn --workers 1 -k gevent --chdir config config.wsgi:application -b 0.0.0.0:8000

با فلگ -k نوع کلاس ورکر رو مشخص میکنیم. حالا چرا از gevent استفاده میکنیم؟
کتابخونه gevent برای مدریریت همزمانی طراحی شده. میشه گفت یک نمونه lightweight thread هستش که این مدل موقع عملیات های IO سوئیچینگ انجام میده و در این صورت اگه به io خوردید براتون هندل میکنه.

کلی نکات دیگه هم قطعا هست که تو یه پست جا نمیشه
امیدوارم براتون مفید باشه

#python #django #gunicorn #gevent

@Syntax_fa
👍154🔥1🙏1
Linter & pylint

لینتر ابزاری است که برای تحلیل کد استفاده می‌شود تا مشکلات احتمالی در کد را شناسایی کند. این ابزارها به توسعه‌دهندگان کمک می‌کنند تا با شناسایی خطاهای سینتکس، استانداردهای کدنویسی و مسائلی مانند memory leak و ... را شناسایی کنند و کیفیت کد را بهبود بخشند.

کاربردهای Linter


1. شناسایی خطاهای سینتکسی:
لینتر می‌توانند خطاهای سینتکسی را قبل از اجرای کد شناسایی کنند.

2. بهبود خوانایی کد:
با پیشنهادهایی برای رعایت استانداردهای کدنویسی می دهد، خوانایی کد را افزایش می‌دهند.

3. کاهش باگ‌ها:
با شناسایی مسائل بالقوه، به کاهش تعداد باگ‌ها کمک می‌کنند.

4. یکنواختی کد:
با اطمینان از رعایت استانداردهای یکسان در سراسر پروژه، یکنواختی کد را حفظ می‌کنند.

معرفی Pylint

پای لینت یک ابزار Linter برای زبان Python است که به تحلیل کد Python می‌پردازد تا مشکلات مختلفی مانند خطاهای سینتکسی عدم رعایت استانداردهای PEP 8 و مسائل منطقی را شناسایی کند.

ویژگی‌های Pylint


- شناسایی خطاهای نحوی و منطقی:
Pylint می‌تواند خطاهای نحوی و منطقی را در کد شناسایی کند.

- پیشنهاد برای بهبود کد:
با ارائه پیشنهادهایی برای بهبود کد، توسعه‌دهندگان را در نوشتن کدهای تمیزتر و بهینه‌تر یاری می‌دهد.

- پشتیبانی از استانداردهای PEP 8:
با بررسی کد نسبت به استانداردهای PEP 8، به رعایت بهترین شیوه‌های کدنویسی کمک می‌کند.

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

مثال نحوه استفاده از pylint:
pip install pylint

بعد از نصب کردن با دستور
pylint .

تمامی کد های پروژه را بررسی می کند.
خیلی مواقع نیاز است که لینتر ها و تنظیماتشان را تغییر بدهیم. برای اینکار دستور زیر را میزنیم تا فایل کانفیگ لینتر ساخته شود:
pylint --generate-rcfile > .pylintrc

در فایل .pylintrc می توانید بر حسب نیاز خودتان برخی از لینتر هارا غیر فعال کنید یا تنظیماتشان را تغییر دهید.

نحوه استفاده کاربردی از لینتر:
میتوانید در github workflow از لینتر استفاده کنید و اگر مشکلی شناسایی شد اکشن با خطا مواجه شود. همچنین می توانید از ابزار pre commit استفاده کنید و لینتر را تعریف کنید تا هر زمانی که کامیت جدیدی زده میشود بررسی کند اگر خطایی وجود دارد جلوی کامیت را بگیرد.

#linter #pylint #python

@Syntax_fa
1🔥6👍4
توی پایتون بجای isinstance از singledispatch استفاده کن!

۱. ابتدا دو کلاس با استفاده از @dataclass تعریف میکنیم:
@dataclass
class UserCanceledSubscription:
username: str

@dataclass
class UserSubscribed:
username: str

این‌ها دو نوع ایونت هستند: یکی برای زمانی که کاربر مشترک می‌شود و دیگری برای زمانی که اشتراکش را لغو می‌کند.

۲. روش اول با استفاده از isinstance:
def process(event):
if isinstance(event, UserSubscribed):
print(f"Enable access to user {event.username}")
elif isinstance(event, UserCanceledSubscription):
print(f"Disable access to user {event.username}")

در این روش، برای هر نوع رویداد یک شرط if نوشته شده که نوع رویداد را چک می‌کند.

۳. روش دوم با استفاده از singledispatch:
@singledispatch
def process(event):
pass

@process.register(UserCanceledSubscription)
def _(event):
print(f"Disable access to user {event.username}")

@process.register(UserSubscribed)
def _(event):
print(f"Enable access to user {event.username}")

در این روش، برای هر نوع رویداد یک تابع جداگانه تعریف می‌شود که فقط برای آن نوع خاص اجرا می‌شود.

مزایای استفاده از singledispatch:

۱. کد تمیزتر: به جای زنجیره‌ای از `if/elif`، هر منطق در یک تابع جداگانه قرار می‌گیرد.

۲. قابلیت توسعه بهتر: اضافه کردن نوع جدید فقط نیاز به اضافه کردن یک تابع جدید دارد، نه تغییر کد موجود.

۳. جداسازی مسئولیت‌ها: هر تابع فقط مسئول پردازش یک نوع خاص است.

۴. کاهش پیچیدگی: به جای یک تابع بزرگ با شرط‌های متعدد، چندین تابع کوچک و ساده داریم.

نحوه کار:
- @singledispatch
یک تابع پایه تعریف می‌کند
- @process.register()
توابع مختلف را برای انواع مختلف ورودی ثبت می‌کند
- در زمان اجرا، بر اساس نوع ورودی، تابع مناسب فراخوانی می‌شود

کاربرد این الگو در مواردی مثل:
- پردازش انواع مختلف پیام‌ها یا رویدادها
- تبدیل داده‌ها بین فرمت‌های مختلف
- اعمال عملیات‌های متفاوت روی انواع مختلف داده
- پیاده‌سازی الگوی Observer یا Event Handler

نمونه استفاده نهایی:
events = [
UserSubscribed(username="johndoe"),
UserCanceledSubscription(username="johndoe"),
]

for event in events:
process(event)


این کد به طور خودکار تابع مناسب را برای هر نوع رویداد فراخوانی می‌کند.

#python #singledispatch

@Syntax_fa
👍17❤‍🔥2🔥1😁1