我不知道如何对变量进行赋值检查,就像在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
重命名了该问题,因为它与发生的情况不符
答案 0 :(得分:0)
如果要检查该值,只需将检查代码添加到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
校验代码的略微修改。
答案 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就可以逃脱。)