از طریق منوی جستجو مطلب مورد نظر خود در وبلاگ را به سرعت پیدا کنید
دکوراتور دارایی پایتون
ایجاد گیرنده و تنظیم کننده برای ویژگی های عمومی یک کلاس اغلب بهترین روش در نظر گرفته می شود. بسیاری از زبان ها به شما این امکان را می دهند که این را به روش های مختلف پیاده سازی کنید، یا با استفاده از یک تابع (مانند person.getName()
)، یا با استفاده از یک زبان خاص get
یا set
ساختن. در پایتون با استفاده از آن انجام می شود @property
.
در این مقاله، دکوراتورهای دارایی پایتون را توضیح خواهم داد، که ممکن است دیده باشید که با @decorator
نحو:
class Person(object):
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
@property
def full_name(self):
return self.first_name + ' ' + self.last_name
@full_name.setter
def full_name(self, value):
first_name, last_name = value.split(' ')
self.first_name = first_name
self.last_name = last_name
@full_name.deleter
def full_name(self):
del self.first_name
del self.last_name
این روش پایتون برای ایجاد گیرنده، تنظیم کننده و حذف کننده (یا روش های جهش دهنده) برای یک ملک در یک کلاس.
در این مورد، @property
دکوراتور آن را می سازد، بنابراین شما تماس بگیرید full_name(self)
متد مانند آن فقط یک ویژگی معمولی است، در حالی که در واقع متدی است که حاوی کدی است که باید هنگام تنظیم ویژگی اجرا شود.
استفاده از یک گیرنده/ستتر/حذف کننده مانند این چندین مزیت را برای ما به ارمغان میآورد که تعدادی از آنها را در اینجا فهرست کردهام:
- اعتبارسنجی: قبل از تنظیم ویژگی داخلی، میتوانید تأیید کنید که مقدار ارائهشده برخی از معیارها را برآورده میکند و اگر این کار را نکرد، از آن بخواهید که خطا بدهد.
- بارگذاری تنبل: منابع می توانند توسط تنبل بار شده به تعویق انداختن کار تا زمانی که واقعاً مورد نیاز باشد، در زمان و منابع صرفه جویی کنید
- Abstraction: دریافتکنندهها و تنظیمکنندهها به شما این امکان را میدهند که نمایش داخلی دادهها را انتزاع کنید. مانند مثال بالا، برای مثال، نام و نام خانوادگی جداگانه ذخیره می شوند، اما گیرنده ها و تنظیم کننده ها حاوی منطقی هستند که از نام و نام خانوادگی برای ایجاد نام کامل استفاده می کند.
- اشکال زدایی: از آنجایی که متدهای mutator می توانند هر کدی را کپسوله کنند، در هنگام اشکال زدایی (یا ثبت) کد شما مکانی عالی برای رهگیری می شود. برای مثال، میتوانید هر بار که مقدار یک ویژگی تغییر میکند، وارد شوید یا بازرسی کنید.
پایتون این قابلیت را با دکوراتورها به دست میآورد که روشهای خاصی برای تغییر رفتار یک تابع یا کلاس دیگر هستند. به منظور توصیف چگونگی @property
دکوراتور کار می کند، بیایید نگاهی به یک دکوراتور ساده تر و روش عملکرد داخلی آن بیندازیم.
دکوراتور به سادگی تابعی است که تابع دیگری را به عنوان آرگومان می گیرد و با پیچیدن آن به رفتار خود می افزاید. در اینجا یک مثال ساده است:
def some_func():
print 'Hey, you guys'
def my_decorator(func):
def inner():
print 'Before func!'
func()
print 'After func!'
return inner
print 'some_func():'
some_func()
print ''
some_func_decorated = my_decorator(some_func)
print 'some_func() with decorator:'
some_func_decorated()
اجرای این کد به شما می دهد:
$ python decorator.py
some_func():
Hey, you guys
some_func() with decorator:
Before func!
Hey, you guys
After func!
همانطور که می بینید، my_decorator()
تابع به صورت پویا یک تابع جدید برای بازگشت با استفاده از تابع ورودی ایجاد می کند و کدی را اضافه می کند تا قبل و بعد از اجرای تابع اصلی اجرا شود.
را property
دکوراتور با الگوی مشابه اجرا شده است my_decorator
تابع. با استفاده از پایتون @decorator
نحو، تابع تزئین شده را به عنوان آرگومان دریافت می کند، درست مانند مثال من: some_func_decorated = my_decorator(some_func)
.
بنابراین، به اولین مثال من، این کد برمی گردیم:
@property
def full_name_getter(self):
return self.first_name + ' ' + self.last_name
تقریباً معادل این است:
def full_name_getter(self):
return self.first_name + ' ' + self.last_name
full_name = property(full_name_getter)
توجه داشته باشید که من برخی از نام های تابع را برای وضوح تغییر دادم.
بعد، بعد روی زمانی که می خواهید استفاده کنید @full_name.setter
همانطور که در مثال انجام می دهیم، چیزی که شما واقعاً با آن تماس می گیرید این است:
def full_name_setter(self, value):
first_name, last_name = value.split(' ')
self.first_name = first_name
self.last_name = last_name
full_name = property(full_name_getter)
full_name = full_name.setter(full_name_setter)
حالا این جدیده full_name
شی (نمونه ای از property
شی) دارای هر دو روش گیرنده و تنظیم کننده است.
برای استفاده از اینها با کلاس خود، Person
، property
شی به عنوان توصیفگر عمل می کند، به این معنی که خود را دارد __گرفتن__()، __تنظیم__() و __حذف__() مواد و روش ها. را __get__()
و __set__()
روش ها راه اندازی می شوند روی یک شی زمانی که یک ویژگی بازیابی یا تنظیم می شود، و __delete__()
زمانی فعال می شود که یک ویژگی با حذف شود del
.
بنابراین person.full_name = 'Billy Bob'
باعث می شود __set__()
روشی که از آن به ارث رسیده است object
. این ما را به یک نکته مهم می رساند – کلاس شما باید از آن ارث ببرد object
برای اینکه این کار کند. بنابراین کلاسی مانند این خواهد بود نه قادر به استفاده از ویژگی های تنظیم کننده باشد زیرا از آن ارث نمی برد object
:
class Person:
pass
با تشکر از property
، این روش ها اکنون با ما مطابقت دارند full_name_getter
و full_name_setter
روش های بالا:
full_name.fget is full_name_getter
full_name.fset is full_name_setter
fget
و fset
در حال حاضر توسط پیچیده شده است .__get__()
و .__set__()
، به ترتیب.
و در نهایت، این اشیاء توصیفگر را می توان با ارسال یک مرجع به کلاس ما دسترسی داشت. Person
:
>>> person = Person('Billy', 'Bob')
>>>
>>> full_name.__get__(person)
Billy Bob
>>>
>>> full_name.__set__(person, 'Timmy Thomas')
>>>
>>> person.first_name
Timmy
>>> person.last_name
Thomas
این اساساً روش عملکرد خواص زیر سطح است.
(برچسبها به ترجمه)# python
منتشر شده در 1403-01-30 07:40:12