تسلط بر بسته ها و دکوراتورها در پایتون: از مبانی تا پیشرفته
Summarize this content to 400 words in Persian Lang
مقدمه
بستهها و دکوراتورها ویژگیهای قدرتمندی در پایتون هستند که به شما امکان میدهند کدهای انعطافپذیرتر و قابل استفادهتر بنویسید. درک این مفاهیم، مهارتهای پایتون شما را به سطح بعدی میبرد و به شما این امکان را میدهد تا سناریوهای پیچیدهتری مانند ثبتنام، کنترل دسترسی و حافظهسازی را به راحتی مدیریت کنید.
در این پست وبلاگ بررسی خواهیم کرد:
تعطیلی چیست؟
درک نحوه کار بستن در پایتون
از موارد برای بسته شدن استفاده کنید
دکوراتورها چیست؟
درک نحوه کار دکوراتورها
استفاده از دکوراتورهای داخلی
نوشتن دکوراتورهای سفارشی
مفاهیم پیشرفته با دکوراتورها
در پایان این مقاله، درک کاملی از بستهها و دکوراتورها خواهید داشت و میتوانید آنها را به طور موثر در کد خود اعمال کنید.
بسته شدن چیست؟
در پایتون، بسته شدن توابعی هستند که مقادیر متغیرها را از محدوده واژگانی محصور خود حفظ می کنند، حتی زمانی که اجرای تابع بیرونی به پایان رسیده است. بسته شدن روشی برای حفظ حالت بین فراخوانیهای تابع است که آنها را برای سناریوهایی مفید میکند که در آنها نیاز به حفظ محتوایی دارید.
بسته شدن از سه جزء اصلی تشکیل شده است:
یک تابع تو در تو
ارجاع به یک متغیر آزاد در تابع محصور کننده
اجرای تابع محصور کننده به پایان رسیده است، اما تابع تودرتو هنوز وضعیت متغیر آزاد را به خاطر می آورد.
مثال اصلی یک بسته
در اینجا نمونه ای از بسته شدن ساده آورده شده است:
def outer_function(message):
def inner_function():
print(message)
return inner_function
# Create a closure
closure = outer_function(“Hello, World!”)
closure() # Output: Hello, World!
در این مثال، inner_function ارجاع به message متغیر از outer_function، حتی بعد از outer_function اجرا به پایان رسیده است تابع درونی “بر روی” متغیر از محدوده بیرونی بسته می شود، از این رو اصطلاح بسته شدن.
نحوه بسته شدن در داخل
بسته شدن با گرفتن وضعیت متغیرهای آزاد و ذخیره آنها در شی تابع کار می کند __closure__ ویژگی
بیایید بسته شدن را از مثال قبلی بررسی کنیم:
print(closure.__closure__[0].cell_contents) # Output: Hello, World!
این __closure__ ویژگی ارجاع به متغیرهایی را که بسته شدن حفظ می کند نگه می دارد. هر متغیر در یک “سلول” ذخیره می شود و شما می توانید با استفاده از آن به محتوای آن دسترسی داشته باشید cell_contents.
از موارد برای بسته شدن استفاده کنید
بستن ها به ویژه زمانی مفید هستند که بخواهید وضعیت بین فراخوانی های تابع را بدون استفاده از متغیرها یا کلاس های سراسری حفظ کنید. در اینجا چند مورد استفاده رایج آورده شده است:
1. کارخانجات عملکردی
برای ایجاد پویا توابع می توانید از بسته ها استفاده کنید.
def multiplier(factor):
def multiply_by_factor(number):
return number * factor
return multiply_by_factor
times_two = multiplier(2)
times_three = multiplier(3)
print(times_two(5)) # Output: 10
print(times_three(5)) # Output: 15
در این مثال، multiplier تابعی را برمی گرداند که یک عدد معین را در یک عامل خاص ضرب می کند. تعطیلی ها times_two و times_three ارزش را حفظ کند factor از محدوده محصور آنها.
2. کپسولاسیون
بسته شدن به شما این امکان را می دهد که رفتار را بدون افشای وضعیت داخلی محصور کنید. این شبیه به مفهوم روش های خصوصی در برنامه نویسی شی گرا است.
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
counter_fn = counter()
print(counter_fn()) # Output: 1
print(counter_fn()) # Output: 2
در این مثال، count متغیر در داخل بسته محصور شده است، و تنها increment تابع می تواند مقدار خود را تغییر دهد.
دکوراتورها چیست؟
الف دکوراتور تابعی است که تابع دیگری را می گیرد و رفتار خود را بدون تغییر کد تابع اصلی گسترش می دهد یا تغییر می دهد. دکوراتورها اغلب برای افزودن قابلیت هایی مانند ورود به سیستم، کنترل دسترسی یا زمان بندی به عملکردها و روش ها استفاده می شوند.
در پایتون، دکوراتورها با استفاده از توابع به کار می روند @ نماد بالای تعریف تابع
مثال اصلی یک دکوراتور
def decorator_function(original_function):
def wrapper_function():
print(f”Wrapper executed before {original_function.__name__}()”)
return original_function()
return wrapper_function
@decorator_function
def say_hello():
print(“Hello!”)
say_hello()
# Output:
# Wrapper executed before say_hello()
# Hello!
اینجا، decorator_function اعمال می شود say_hello، اضافه کردن عملکرد اضافی قبل از say_hello() اجرا می کند.
نحوه کار دکوراتورها
دکوراتورها اساساً قند نحوی برای یک الگوی رایج در پایتون هستند: توابع مرتبه بالاتر، که توابع دیگر را به عنوان آرگومان می گیرند. وقتی می نویسی @decorator، معادل است با:
say_hello = decorator_function(say_hello)
تابع دکوراتور یک عملکرد جدید برمی گرداند (wrapper_function) که رفتار تابع اصلی را گسترش می دهد.
دکوراتورها با استدلال
اگر تابعی که تزئین میشود آرگومانها را بگیرد، تابع wrapper باید بپذیرد *args و **kwargs برای انتقال استدلال ها.
def decorator_function(original_function):
def wrapper_function(*args, **kwargs):
print(f”Wrapper executed before {original_function.__name__}()”)
return original_function(*args, **kwargs)
return wrapper_function
@decorator_function
def display_info(name, age):
print(f”display_info ran with arguments ({name}, {age})”)
display_info(“John”, 25)
# Output:
# Wrapper executed before display_info()
# display_info ran with arguments (John, 25)
دکوراتورهای داخلی در پایتون
پایتون چندین دکوراتور داخلی مانند @staticmethod، @classmethod، و @property.
@staticmethod و @classmethod
این دکوراتورها معمولاً در برنامه نویسی شی گرا برای تعریف روش هایی استفاده می شوند که یا به نمونه محدود نمی شوند (@staticmethod) یا محدود به خود کلاس (@classmethod).
class MyClass:
@staticmethod
def static_method():
print(“Static method called”)
@classmethod
def class_method(cls):
print(f”Class method called from {cls}”)
MyClass.static_method() # Output: Static method called
MyClass.class_method() # Output: Class method called from <class ‘__main__.MyClass’>
@property
این @property decorator به شما امکان می دهد تا روشی را تعریف کنید که مانند یک ویژگی قابل دسترسی باشد.
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value <= 0:
raise ValueError(“Radius must be positive”)
self._radius = value
c = Circle(5)
print(c.radius) # Output: 5
c.radius = 10
print(c.radius) # Output: 10
نوشتن دکوراتورهای سفارشی
شما می توانید دکوراتورهای خود را بنویسید تا عملکردهای سفارشی را به عملکردها یا روش های خود اضافه کنید. دکوراتورها را می توان انباشته کرد، به این معنی که می توانید چندین دکوراتور را برای یک عملکرد واحد اعمال کنید.
مثال: زمان بندی یک تابع
در اینجا یک دکوراتور سفارشی است که زمان اجرای یک تابع را اندازه گیری می کند:
import time
def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f”{func.__name__} ran in {end_time – start_time:.4f} seconds”)
return result
return wrapper
@timer_decorator
def calculate_square(numbers):
result = [n * n for n in numbers]
return result
nums = range(1, 1000000)
calculate_square(nums)
دکوراتورها با استدلال
دکوراتورها نیز می توانند استدلال های خود را بپذیرند. این زمانی مفید است که شما باید مقادیر پیکربندی را به دکوراتور منتقل کنید.
مثال: Logger با پیام سفارشی
def logger_decorator(message):
def decorator(func):
def wrapper(*args, **kwargs):
print(f”{message}: Executing {func.__name__}”)
return func(*args, **kwargs)
return wrapper
return decorator
@logger_decorator(“DEBUG”)
def greet(name):
print(f”Hello, {name}!”)
greet(“Alice”)
# Output:
# DEBUG: Executing greet
# Hello, Alice!
در این مثال، دکوراتور logger_decorator یک پیام را به عنوان یک استدلال می گیرد و سپس آن را می پیچد greet عملکرد با قابلیت ورود به سیستم اضافی.
مفاهیم دکوراتور پیشرفته
1. کلاس های تزئین
دکوراتورها را می توان نه تنها برای عملکردها بلکه برای کلاس ها نیز به کار برد. دکوراتورهای کلاس رفتار کل کلاس ها را اصلاح یا گسترش می دهند.
def add_str_repr(cls):
cls.__str__ = lambda self: f”Instance of {cls.__name__}”
return cls
@add_str_repr
class Dog:
pass
dog = Dog()
print(dog) # Output: Instance of Dog
2. یادداشت با دکوراتورها
حافظهگذاری یک تکنیک بهینهسازی است که در آن نتایج فراخوانیهای تابع گران قیمت در حافظه پنهان ذخیره میشوند، بنابراین تماسهای بعدی با همان آرگومانها میتوانند سریعتر برگردانده شوند.
def memoize(func):
cache = {}
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def fibonacci(n):
if n in [0, 1]:
return n
return fibonacci(n – 1) + fibonacci(n – 2)
print(fibonacci(30)) # Output: 832040
نتیجه گیری
بستهها و دکوراتورها مفاهیم پیشرفته پایتون هستند که قابلیتهای قدرتمندی را برای نوشتن کدهای تمیزتر و کارآمدتر باز میکنند. بستهها به شما امکان میدهند حالت را حفظ کنید و دادهها را محصور کنید، در حالی که دکوراتورها به شما امکان میدهند رفتار عملکردها و روشها را به روشی قابل استفاده مجدد تغییر دهید یا گسترش دهید. چه در حال بهینهسازی عملکرد با حافظهگذاری، پیادهسازی کنترل دسترسی یا اضافه کردن گزارشگیری باشید، دکوراتورها یک ابزار ضروری در جعبه ابزار پایتون شما هستند.
با تسلط بر این مفاهیم، قادر خواهید بود کدهای مختصر و قابل نگهداری بیشتری بنویسید و وظایف برنامه نویسی پیچیده را به راحتی انجام دهید.
با خیال راحت در پروژه های خود با بسته ها و دکوراتورها آزمایش کنید و کشف کنید که چگونه می توانند کد شما را زیباتر و قدرتمندتر کنند!
با من ارتباط برقرار کن
GitHub
لینکدین
مقدمه
بستهها و دکوراتورها ویژگیهای قدرتمندی در پایتون هستند که به شما امکان میدهند کدهای انعطافپذیرتر و قابل استفادهتر بنویسید. درک این مفاهیم، مهارتهای پایتون شما را به سطح بعدی میبرد و به شما این امکان را میدهد تا سناریوهای پیچیدهتری مانند ثبتنام، کنترل دسترسی و حافظهسازی را به راحتی مدیریت کنید.
در این پست وبلاگ بررسی خواهیم کرد:
- تعطیلی چیست؟
- درک نحوه کار بستن در پایتون
- از موارد برای بسته شدن استفاده کنید
- دکوراتورها چیست؟
- درک نحوه کار دکوراتورها
- استفاده از دکوراتورهای داخلی
- نوشتن دکوراتورهای سفارشی
- مفاهیم پیشرفته با دکوراتورها
در پایان این مقاله، درک کاملی از بستهها و دکوراتورها خواهید داشت و میتوانید آنها را به طور موثر در کد خود اعمال کنید.
بسته شدن چیست؟
در پایتون، بسته شدن توابعی هستند که مقادیر متغیرها را از محدوده واژگانی محصور خود حفظ می کنند، حتی زمانی که اجرای تابع بیرونی به پایان رسیده است. بسته شدن روشی برای حفظ حالت بین فراخوانیهای تابع است که آنها را برای سناریوهایی مفید میکند که در آنها نیاز به حفظ محتوایی دارید.
بسته شدن از سه جزء اصلی تشکیل شده است:
- یک تابع تو در تو
- ارجاع به یک متغیر آزاد در تابع محصور کننده
- اجرای تابع محصور کننده به پایان رسیده است، اما تابع تودرتو هنوز وضعیت متغیر آزاد را به خاطر می آورد.
مثال اصلی یک بسته
در اینجا نمونه ای از بسته شدن ساده آورده شده است:
def outer_function(message):
def inner_function():
print(message)
return inner_function
# Create a closure
closure = outer_function("Hello, World!")
closure() # Output: Hello, World!
در این مثال، inner_function
ارجاع به message
متغیر از outer_function
، حتی بعد از outer_function
اجرا به پایان رسیده است تابع درونی “بر روی” متغیر از محدوده بیرونی بسته می شود، از این رو اصطلاح بسته شدن.
نحوه بسته شدن در داخل
بسته شدن با گرفتن وضعیت متغیرهای آزاد و ذخیره آنها در شی تابع کار می کند __closure__
ویژگی
بیایید بسته شدن را از مثال قبلی بررسی کنیم:
print(closure.__closure__[0].cell_contents) # Output: Hello, World!
این __closure__
ویژگی ارجاع به متغیرهایی را که بسته شدن حفظ می کند نگه می دارد. هر متغیر در یک “سلول” ذخیره می شود و شما می توانید با استفاده از آن به محتوای آن دسترسی داشته باشید cell_contents
.
از موارد برای بسته شدن استفاده کنید
بستن ها به ویژه زمانی مفید هستند که بخواهید وضعیت بین فراخوانی های تابع را بدون استفاده از متغیرها یا کلاس های سراسری حفظ کنید. در اینجا چند مورد استفاده رایج آورده شده است:
1. کارخانجات عملکردی
برای ایجاد پویا توابع می توانید از بسته ها استفاده کنید.
def multiplier(factor):
def multiply_by_factor(number):
return number * factor
return multiply_by_factor
times_two = multiplier(2)
times_three = multiplier(3)
print(times_two(5)) # Output: 10
print(times_three(5)) # Output: 15
در این مثال، multiplier
تابعی را برمی گرداند که یک عدد معین را در یک عامل خاص ضرب می کند. تعطیلی ها times_two
و times_three
ارزش را حفظ کند factor
از محدوده محصور آنها.
2. کپسولاسیون
بسته شدن به شما این امکان را می دهد که رفتار را بدون افشای وضعیت داخلی محصور کنید. این شبیه به مفهوم روش های خصوصی در برنامه نویسی شی گرا است.
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
counter_fn = counter()
print(counter_fn()) # Output: 1
print(counter_fn()) # Output: 2
در این مثال، count
متغیر در داخل بسته محصور شده است، و تنها increment
تابع می تواند مقدار خود را تغییر دهد.
دکوراتورها چیست؟
الف دکوراتور تابعی است که تابع دیگری را می گیرد و رفتار خود را بدون تغییر کد تابع اصلی گسترش می دهد یا تغییر می دهد. دکوراتورها اغلب برای افزودن قابلیت هایی مانند ورود به سیستم، کنترل دسترسی یا زمان بندی به عملکردها و روش ها استفاده می شوند.
در پایتون، دکوراتورها با استفاده از توابع به کار می روند @
نماد بالای تعریف تابع
مثال اصلی یک دکوراتور
def decorator_function(original_function):
def wrapper_function():
print(f"Wrapper executed before {original_function.__name__}()")
return original_function()
return wrapper_function
@decorator_function
def say_hello():
print("Hello!")
say_hello()
# Output:
# Wrapper executed before say_hello()
# Hello!
اینجا، decorator_function
اعمال می شود say_hello
، اضافه کردن عملکرد اضافی قبل از say_hello()
اجرا می کند.
نحوه کار دکوراتورها
دکوراتورها اساساً قند نحوی برای یک الگوی رایج در پایتون هستند: توابع مرتبه بالاتر، که توابع دیگر را به عنوان آرگومان می گیرند. وقتی می نویسی @decorator
، معادل است با:
say_hello = decorator_function(say_hello)
تابع دکوراتور یک عملکرد جدید برمی گرداند (wrapper_function
) که رفتار تابع اصلی را گسترش می دهد.
دکوراتورها با استدلال
اگر تابعی که تزئین میشود آرگومانها را بگیرد، تابع wrapper باید بپذیرد *args
و **kwargs
برای انتقال استدلال ها.
def decorator_function(original_function):
def wrapper_function(*args, **kwargs):
print(f"Wrapper executed before {original_function.__name__}()")
return original_function(*args, **kwargs)
return wrapper_function
@decorator_function
def display_info(name, age):
print(f"display_info ran with arguments ({name}, {age})")
display_info("John", 25)
# Output:
# Wrapper executed before display_info()
# display_info ran with arguments (John, 25)
دکوراتورهای داخلی در پایتون
پایتون چندین دکوراتور داخلی مانند @staticmethod
، @classmethod
، و @property
.
@staticmethod
و @classmethod
این دکوراتورها معمولاً در برنامه نویسی شی گرا برای تعریف روش هایی استفاده می شوند که یا به نمونه محدود نمی شوند (@staticmethod
) یا محدود به خود کلاس (@classmethod
).
class MyClass:
@staticmethod
def static_method():
print("Static method called")
@classmethod
def class_method(cls):
print(f"Class method called from {cls}")
MyClass.static_method() # Output: Static method called
MyClass.class_method() # Output: Class method called from <class '__main__.MyClass'>
@property
این @property
decorator به شما امکان می دهد تا روشی را تعریف کنید که مانند یک ویژگی قابل دسترسی باشد.
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value <= 0:
raise ValueError("Radius must be positive")
self._radius = value
c = Circle(5)
print(c.radius) # Output: 5
c.radius = 10
print(c.radius) # Output: 10
نوشتن دکوراتورهای سفارشی
شما می توانید دکوراتورهای خود را بنویسید تا عملکردهای سفارشی را به عملکردها یا روش های خود اضافه کنید. دکوراتورها را می توان انباشته کرد، به این معنی که می توانید چندین دکوراتور را برای یک عملکرد واحد اعمال کنید.
مثال: زمان بندی یک تابع
در اینجا یک دکوراتور سفارشی است که زمان اجرای یک تابع را اندازه گیری می کند:
import time
def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} ran in {end_time - start_time:.4f} seconds")
return result
return wrapper
@timer_decorator
def calculate_square(numbers):
result = [n * n for n in numbers]
return result
nums = range(1, 1000000)
calculate_square(nums)
دکوراتورها با استدلال
دکوراتورها نیز می توانند استدلال های خود را بپذیرند. این زمانی مفید است که شما باید مقادیر پیکربندی را به دکوراتور منتقل کنید.
مثال: Logger با پیام سفارشی
def logger_decorator(message):
def decorator(func):
def wrapper(*args, **kwargs):
print(f"{message}: Executing {func.__name__}")
return func(*args, **kwargs)
return wrapper
return decorator
@logger_decorator("DEBUG")
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# Output:
# DEBUG: Executing greet
# Hello, Alice!
در این مثال، دکوراتور logger_decorator
یک پیام را به عنوان یک استدلال می گیرد و سپس آن را می پیچد greet
عملکرد با قابلیت ورود به سیستم اضافی.
مفاهیم دکوراتور پیشرفته
1. کلاس های تزئین
دکوراتورها را می توان نه تنها برای عملکردها بلکه برای کلاس ها نیز به کار برد. دکوراتورهای کلاس رفتار کل کلاس ها را اصلاح یا گسترش می دهند.
def add_str_repr(cls):
cls.__str__ = lambda self: f"Instance of {cls.__name__}"
return cls
@add_str_repr
class Dog:
pass
dog = Dog()
print(dog) # Output: Instance of Dog
2. یادداشت با دکوراتورها
حافظهگذاری یک تکنیک بهینهسازی است که در آن نتایج فراخوانیهای تابع گران قیمت در حافظه پنهان ذخیره میشوند، بنابراین تماسهای بعدی با همان آرگومانها میتوانند سریعتر برگردانده شوند.
def memoize(func):
cache = {}
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def fibonacci(n):
if n in [0, 1]:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print(fibonacci(30)) # Output: 832040
نتیجه گیری
بستهها و دکوراتورها مفاهیم پیشرفته پایتون هستند که قابلیتهای قدرتمندی را برای نوشتن کدهای تمیزتر و کارآمدتر باز میکنند. بستهها به شما امکان میدهند حالت را حفظ کنید و دادهها را محصور کنید، در حالی که دکوراتورها به شما امکان میدهند رفتار عملکردها و روشها را به روشی قابل استفاده مجدد تغییر دهید یا گسترش دهید. چه در حال بهینهسازی عملکرد با حافظهگذاری، پیادهسازی کنترل دسترسی یا اضافه کردن گزارشگیری باشید، دکوراتورها یک ابزار ضروری در جعبه ابزار پایتون شما هستند.
با تسلط بر این مفاهیم، قادر خواهید بود کدهای مختصر و قابل نگهداری بیشتری بنویسید و وظایف برنامه نویسی پیچیده را به راحتی انجام دهید.
با خیال راحت در پروژه های خود با بسته ها و دکوراتورها آزمایش کنید و کشف کنید که چگونه می توانند کد شما را زیباتر و قدرتمندتر کنند!
با من ارتباط برقرار کن
- GitHub
- لینکدین