Nasıl @özelliğini dekoratör iş yapar?
Yerleşik fonksiyonunu anlamak istiyorum property
çalışır. Benim için kafa karıştırıcı bölümü property
bir dekoratör, bir işlevi dekorasyon için argümanlar yok iken de olabilir.
Bu örnek documentation dan:
class C(object):
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
property
'nın bağımsız değişkenlerigetx
, setx
, delx
ve doktor bir dize.
Aşağıdaki kod property
dekoratör olarak kullanılır. Amaç x
işlevi vardır, ama yukarıdaki kod içinde bağımsız bir nesne işlevi için yer yoktur.
class C(object):
def __init__(self):
self._x = None
@property
def x(self):
"""I'm the 'x' property."""
return self._x
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
Ve nasıl x.setter
x.deleter
dekoratörler yarattı?
Kafam karıştı.
CEVAP
property()
işlev bir özel descriptor object:
>>> property()
<property object at 0x10ff07940>
Bu nesneekstrayöntem:
>>> property().getter
<built-in method getter of property object at 0x10ff07998>
>>> property().setter
<built-in method setter of property object at 0x10ff07940>
>>> property().deleter
<built-in method deleter of property object at 0x10ff07998>
Bu dekoratör olarak hareket ederlerçok. Onlar yeni bir özellik bir nesne döndürür:
>>> property().getter(None)
<property object at 0x10ff079f0>
bu işlevleri yerine yaşlı bir nesne, ama bir kopyasıdır.
@decorator
sözdizimi sadece sözdizimsel şeker olduğunu unutmayın; sözdizimi:
@property
def foo(self): return self._foo
gerçekten aynı şeyi ifade ediyor
def foo(self): return self._foo
foo = property(foo)
foo
işlevi gördük yukarıda özel bir nesne olan property(foo)
tarafından değiştirilir. Ne yaptığını kullandığınızda @foo.setter()
, bir kopyasını verir, yukarıda gösterdim property().setter
bu yöntemi çağırınaynı özellikayarlayıcı işlevi dekore yöntemi ile değiştirilir , ama.
Şu sıra aynı zamanda tam bir özellik, bu dekoratör yöntemleri kullanarak oluşturur.
İlk olarak, bazı işlevler ve sadece bir alıcı ile property
bir nesne oluşturuyoruz:
>>> def getter(self): print 'Get!'
...
>>> def setter(self, value): print 'Set to {!r}!'.format(value)
...
>>> def deleter(self): print 'Delete!'
...
>>> prop = property(getter)
>>> prop.fget is getter
True
>>> prop.fset is None
True
>>> prop.fdel is None
True
Önümüzdeki bir pasör eklemek için .setter()
yöntemini kullanırız:
>>> prop = prop.setter(setter)
>>> prop.fget is getter
True
>>> prop.fset is setter
True
>>> prop.fdel is None
True
Son .deleter()
yöntemi ile deleter ekliyoruz:
>>> prop = prop.deleter(deleter)
>>> prop.fget is getter
True
>>> prop.fset is setter
True
>>> prop.fdel is deleter
True
Son ama en az değil, property
nesne gibi çalışır descriptor object var .__get__()
, .__set__()
.__delete__()
yöntemler için kanca içine örnek öznitelik alma, ayarlama ve silme:
>>> class Foo(object): pass
...
>>> prop.__get__(Foo(), Foo)
Get!
>>> prop.__set__(Foo(), 'bar')
Set to 'bar'!
>>> prop.__delete__(Foo())
Delete!
Tanımlayıcı Nasıl Yapılır property()
türü pure python sample implementation içerir:
class Property(object): "Emulate PyProperty_Type() in Objects/descrobject.c" def __init__(self, fget=None, fset=None, fdel=None, doc=None): self.fget = fget self.fset = fset self.fdel = fdel if doc is None and fget is not None: doc = fget.__doc__ self.__doc__ = doc def __get__(self, obj, objtype=None): if obj is None: return self if self.fget is None: raise AttributeError("unreadable attribute") return self.fget(obj) def __set__(self, obj, value): if self.fset is None: raise AttributeError("can't set attribute") self.fset(obj, value) def __delete__(self, obj): if self.fdel is None: raise AttributeError("can't delete attribute") self.fdel(obj) def getter(self, fget): return type(self)(fget, self.fset, self.fdel, self.__doc__) def setter(self, fset): return type(self)(self.fget, fset, self.fdel, self.__doc__) def deleter(self, fdel): return type(self)(self.fget, self.fset, fdel, self.__doc__)
Nasıl button in yeniden boyutlandırıla...
Nasıl Vekil, Dekoratör, Adaptör ve Köp...
Node.js / Express.js - Nasıl uygulamay...
Nasıl Emacs dosyaları yedekleme yapar ...
Nasıl yeni otomatik referans sayma mek...