如何像猕猴桃一样做支票?

时间:2018-11-23 08:26:17

标签: python kivy

我不知道如何对变量进行赋值检查,就像在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    

在Kivy中可以做到:

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 :(得分:0)

如果要检查该值,只需将检查代码添加到setter中。例如,如果您希望将var限制为intfloat,则可以将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校验代码的略微修改。

答案 1 :(得分:0)

我假设您想对分配进行一些检查,例如在kivy情况下进行类型检查。您的示例在我看来非常简单,我将通过以下方式编写它:

class Foo:

    @property
    def var(self):
        return self._var

    @var.setter
    def var(self, value):
        if type(value) == str:
            self._var = value

它如何工作?实际上,这有点复杂,但是here是很好的资源。 property返回descriptor,这基本上意味着foo.var = x被翻译为foo.var.__set__(x)(然后将其称为“等效”到Foo.var.setter_function(foo, x))。它只是说“而不是存储分配的值,而是调用此函数”。

猕猴桃的情况有何不同?假设我们有以下课程:

class Bar(Widget):
    var = StringProperty()

其行为与之前的python代码非常相似,但是setter和getter方法是由kivy定义的,而不是在类中定义的。但是,如果您为Bar实例bar.var = x分配值,则设置器称为bar.var.__set__(x)。设置器不仅会检查类型,而且还会在值更改时发出事件。

您还可以使用实现descriptor时已经提供的getter和setter创建属性。您需要实现__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)

documentation用get,set,delete和set_name来表示,但我认为在通常情况下,仅实现set和get就可以逃脱。)