Полагаю, вы хотите выполнить некоторые проверки назначений, например, проверку типа в случае с KIVY.Ваш пример выглядит очень однотипно, я бы написал так:
class Foo:
@property
def var(self):
return self._var
@var.setter
def var(self, value):
if type(value) == str:
self._var = value
Как это работает?На самом деле это немного сложно, но здесь - хороший ресурс.property
возвращает дескриптор , который в основном означает, что foo.var = x
переводится в foo.var.__set__(x)
(что затем вызывает нечто "эквивалентное" Foo.var.setter_function(foo, x)
).Он просто говорит «вместо сохранения назначенного значения, вызовите эту функцию».
Чем отличается регистр kivy?Предположим, у нас есть следующий класс:
class Bar(Widget):
var = StringProperty()
Поведение очень похоже на предыдущий код Python, но методы setter и getter определены kivy, а не здесь, в классе.Но если вы присваиваете значение экземпляру Bar bar.var = x
, сеттер называется bar.var.__set__(x)
.Сеттер не только проверяет типы, но и генерирует события, если значение изменилось.
Вы также можете создавать свойства с помощью методов получения и установки, уже предоставленных путем реализации дескриптора .Вам нужно реализовать __set__
и __get__
:
class MyStringProperty:
def __init__(self, default):
self._default = default
def __set__(self, instance, value):
if type(value) == str:
instance._value = value
def __get__(self, instance, owner):
return getattr(instance, "_value", self._default)
class Foo:
var = MyStringProperty("x")
foo = Foo()
print(foo.var)
foo.var = 3
print(foo.var)
foo.var = "asdf"
print(foo.var)
(Документация говорит от get, set, delete и set_name, но я думаю, что в общем случае можно получитьпокончить только с реализацией набора и получения.