دکوراتور ها یه ابزار قدرتمند و کاربردی تو زبان پایتون هستند که به ما اجازه میدن رفتار یه کلاس یا تابع رو تغییر بدیم. دکوراتور ها این امکان رو به ما میدن که قابلیت های تابعمون رو بدون دستکاری خود تابع افزایش بدیم.
در ادامه مطلب یه مثال ازش میبینیم:
ادامه مطلب
در پایتون ارسال اشیای تغییرناپذیر (Immutable) به مانند انواع بولین، اعداد، رشته و تاپل به تابع، باعث بروز رفتاری مشابه با شیوه by value میشود ولی در مورد ارسال اشیای تغییرپذیر (Mutable) به مانند انواع لیست، دیکشنری و مجموعه اینگونه نخواهد بود.
برای جلوگیری از تغییر اشیای تغییرپذیر درون تابع، میتوان یک کپی از این نوع اشیا را ایجاد و سپس به صورت آرگومان به تابع ارسال کرد:
>>> def f(a): . a[0] = 3 . print(a) . >>> b = [1, 2] >>> f(b[:]) # Pass a copy [3, 2] >>> b [1, 2]
در نمونه کد بالا، از آنجایی که تمام اعضای شی لیست متغیر b تماما از انواع تغییرناپذیر هستند، یک کپی سطحی (Shallow Copy) از شی کفایت میکند ولی در حالتی غیر از این میبایست یک کپی عمیق (Deep Copy) از شی ارسال گردد.
با مزایا شروع میکنیم؛ استفاده از iterator ها و generator ها خوب است چون:
1- خاصیت lazy بودن به ما امکان می دهد iterator هایی بسازیم که اندازه ندارند و عملا نامتناهی هستند.
2- مکانیزم iterator از لحاظ حافظه بسیار بهینه است و گاهی حتی چاره ای جز استفاده از iterator نداریم.
3- با استفاده از توابع __next__و یا yield می توان کلاس های بسیار مرتبی نوشت که به صورت کاملا شخصی سازی شده (customized) یک iterator را بسازند. مثال آن می تواند ساختن iterator بر روی یک دیتابیس یا دیتاست باشد.
ادامه مطلب
Bad:
def create_menu(title, body, button_text, cancellable): # .
from dataclasses import astuple, dataclass @dataclass class MenuConfig: """A configuration for the Menu. Attributes: title: The title of the Menu. body: The body of the Menu. button_text: The text for the button label. cancellable: Can it be cancelled? """ title: str body: str button_text: str cancellable: bool = False def create_menu(config: MenuConfig): title, body, button_text, cancellable = astuple(config) # . create_menu( MenuConfig( title="My delicious menu", body="A description of the various items on the menu", button_text="Order now!" ) )
Bad:
def email_clients(clients: List[Client]): """Filter active clients and send them an email. """ for client in clients: if client.active: email(client)
best:
def active_clients(clients: List[Client]) -> Generator[Client]: """Only active clients. """ return (client for client in clients if client.active) def email_client(clients: Iterator[Client]) -> None: """Send an email to a given list of clients. """ for client in clients: email(client)
Bad:
class Airplane { // . public function getCruisingAltitude(): int { switch ($this->type) { case '777': return $this->getMaxAltitude() - $this->getPassengerCount(); case 'Air Force One': return $this->getMaxAltitude(); case 'Cessna': return $this->getMaxAltitude() - $this->getFuelExpenditure(); } } }
Good:
interface Airplane { // . public function getCruisingAltitude(): int; } class Boeing777 implements Airplane { // . public function getCruisingAltitude(): int { return $this->getMaxAltitude() - $this->getPassengerCount(); } } class AirForceOne implements Airplane { // . public function getCruisingAltitude(): int { return $this->getMaxAltitude(); } } class Cessna implements Airplane { // . public function getCruisingAltitude(): int { return $this->getMaxAltitude() - $this->getFuelExpenditure(); } }
درباره این سایت