Как сделать чек как в киве? - PullRequest
0 голосов
/ 23 ноября 2018

Я не понимаю, как сделать проверку присваивания переменной, как это делается в Kivy.Я знаю, как это делается для свойств класса, и это выглядит так

#!/usr/bin/python3.6    
class Foo:
   var = property()
   def __init__(self):
      self._var = 0
   @var.setter
   def var(self, value):
      self._var = value
      # code setter
      pass

   @var.getter
   def var(self):
      # code getter
      print('Getter method')
      return self._var

a = Foo()
a.var = 5
print(a.var)
# Getter method
# 5    

В Киви можно сделать:

class LabelBase(Label):
msg = StringProperty('t')

   def __init__(self, **kwargs):
       super(LabelBase, self).__init__(**kwargs)
       self.msg = 5

Я беру

     Traceback (most recent call last):
   File "/home/Python/Prj/View/Main.py", line 83, in <module>
     Start().build()
   File "/home/Python/Prj/View/Main.py", line 73, in build
     GUI().run()
   File "/usr/lib/python3/dist-packages/kivy/app.py", line 800, in run
     root = self.build()
   File "/home/Python/Prj/View/Main.py", line 65, in build
     main_window = MainFrame()
   File "/home/Python/Prj/View/Main.py", line 52, in __init__
     self.label = LabelBase(text='test')
   File "/home/Python/Prj/View/Main.py", line 16, in __init__
     self.msg = 5
   File "kivy/properties.pyx", line 483, in 
   kivy.properties.Property.__set__
   File "kivy/properties.pyx", line 521, in kivy.properties.Property.set
   File "kivy/properties.pyx", line 512, in kivy.properties.Property.set
   File "kivy/properties.pyx", line 678, in 
   kivy.properties.StringProperty.check
   ValueError: LabelBase.msg accept only str

Переименованвопрос, потому что это не соответствовало тому, что происходило

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Полагаю, вы хотите выполнить некоторые проверки назначений, например, проверку типа в случае с 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, но я думаю, что в общем случае можно получитьпокончить только с реализацией набора и получения.

0 голосов
/ 23 ноября 2018

Если вы хотите проверить значение, просто добавьте код проверки к вашему setter.Например, если вы хотите, чтобы значение var было ограничено int или float, вы можете изменить setter следующим образом:

   @var.setter
   def var(self, value):
      if type(value) not in (int, float):
          raise ValueError('%s.%s accept only int or float (got %r)' % (
              self.__class__.__name__,
              'var', value))
      self._var = value

Этот код представляет собой небольшое изменение проверки Kivyкод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...