Skip to main content
 首页 » 编程设计

python之不鼓励使用 kivy 动态添加属性——为什么

2025年05月04日17EasonJim

kivy.event.EventDispatcher 类有一个名为 apply_property() 的方法它允许在运行时向类添加属性。 文档包含警告:

This method is not recommended for common usage because you should declare the properties in your class instead of using this method.

我不清楚为什么不鼓励这种用法,而首选在类中声明。谁能赐教一下?

请您参考如下方法:

apply_property() 用于将属性添加到单个类实例,但也有污染其他实例属性的副作用。考虑以下代码:

#!/usr/bin/kivy 
import kivy 
kivy.require('1.9.1') 
 
from kivy.app import App 
from kivy.lang import Builder 
from kivy.properties import NumericProperty 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.button import Button 
 
Builder.load_string(''' 
<MyButton>: 
    on_press: print('np' in self.properties()) 
''') 
 
class MyButton(Button): 
    pass 
 
class MainApp(App): 
    def build(self): 
        mb1 = MyButton(text="mb1") 
        mb2 = MyButton(text="mb2") 
        mb1.apply_property(np=NumericProperty(100)) 
 
        layout = BoxLayout() 
        layout.add_widget(mb1) 
        layout.add_widget(mb2) 
        return layout 
 
if __name__ == '__main__': 
    MainApp().run() 

如您所见,即使我在 mb1 实例上使用了 apply_property,mb2 报告它也有这样的属性。这是因为属性被添加到类中,而不是实例中。但是,只有 mb1 具有实际值:

#!/usr/bin/kivy 
import kivy 
kivy.require('1.9.1') 
 
from kivy.app import App 
from kivy.lang import Builder 
from kivy.properties import NumericProperty 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.button import Button 
 
Builder.load_string(''' 
<MyButton>: 
    on_press: print(self.np) 
''') 
 
class MyButton(Button): 
    pass 
 
class MainApp(App): 
    def build(self): 
        mb1 = MyButton(text="mb1") 
        mb2 = MyButton(text="mb2") 
        mb1.apply_property(np=NumericProperty(100)) 
 
        layout = BoxLayout() 
        layout.add_widget(mb1) 
        layout.add_widget(mb2) 
        return layout 
 
if __name__ == '__main__': 
    MainApp().run() 

尝试从 mb2 实例获取 np 属性的值会产生一个 AttributeError。一个安全的选择:

#!/usr/bin/kivy 
import kivy 
kivy.require('1.9.1') 
 
from kivy.app import App 
from kivy.lang import Builder 
from kivy.properties import NumericProperty 
from kivy.uix.boxlayout import BoxLayout 
from kivy.uix.button import Button 
 
Builder.load_string(''' 
<MyButton>: 
    on_press: print(self.np) 
''') 
 
class MyButton(Button): 
    np=NumericProperty(100) 
 
class MainApp(App): 
    def build(self): 
        mb1 = MyButton(text="mb1") 
        mb2 = MyButton(text="mb2") 
 
        layout = BoxLayout() 
        layout.add_widget(mb1) 
        layout.add_widget(mb2) 
        return layout 
 
if __name__ == '__main__': 
    MainApp().run() 

来源:this issue .