【问题标题】:__init__ values vs instantiation value__init__ 值与实例化值
【发布时间】:2014-06-27 07:01:28
【问题描述】:

我是 python 和 kivy 的新手,我被困在 __init__ 变量实例化,我的代码如下:

from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.boxlayout import BoxLayout

spots={}

class spot(Button):
    '''
    classdocs
    '''
    def __init__(self, **kwargs):
        '''
        Constructor
        '''
        super(spot,self).__init__(**kwargs)
        self.ismine=False
        self.text="X"

class game(BoxLayout):        

    def attachtogrid(self):
        self.m.clear_widgets()
        spots.clear()
        for r in range(0,25):
            for c in range(0,25):
                id=str(r)+","+str(c)
                spots[id]=id
                self.m.add_widget(spot(text=id)) 

我的问题是,虽然我将 id 值传递给 text 属性(最后一行代码),但我仍然得到 'X' 作为文本,这在 Spot 类中是默认的;如果我删除默认文本 (self.text="X") 来自 ID 文本正在工作的类。

能否请您澄清上述默认值和实例化差异。谢谢你。

【问题讨论】:

    标签: python python-3.x kivy


    【解决方案1】:

    当您将值id 传递给键text 时,它将作为一对key:value 存储在kwargs 内的字典__init__ 中。 p>

    所以,你可以通过 1

    来访问它
    kwargs['text']
    

    但是,如果用户没有传递参数text,则上面的行(试图访问密钥text)将引发KeyError,因为该密钥不存在。为了解决这个问题,可以使用dictionary.get(key, default)方法:

    self.text = kwargs.get('text', 'X')
    

    它不会引发异常,而是返回默认值。


    1:这是获取与字典中的键对应的值的语法。如果字典中不存在该键,则会引发错误。

    【讨论】:

    • 如果你有一个默认值更简单的方法:self.text = kwargs.get('text', 'X').
    • @glglgl 你是对的。我没有注意到 OP 问题中有一个默认值。已编辑。
    【解决方案2】:
    def __init__(self, **kwargs): # kwargs is a dict containing text
        '''
        Constructor
        '''
        super(spot,self).__init__(**kwargs)
        self.ismine=False
        self.text=kwargs['text'] # you need to assign it here
    

    【讨论】:

    • @surpavan 当您使用参数和/或关键字调用函数时。当您分别执行 *args 和 **kwargs 时,参数会变成一个列表,而关键字参数会变成一个字典。所以你可以这样使用它们。
    【解决方案3】:

    其他答案在一般意义上对 Python 来说是正确的,但它们没有解释 Kivy 的具体情况。

    textStringProperty 上的 Button 类。这意味着只要调用超类构造函数,就不需要在构造函数中赋值,因为 Kivy 会自动处理对 Kivy properties 的赋值。

    例如:

    In [1]: from kivy.uix.button import Button
    
    In [2]: class TestButton(Button):
       ...:     def __init__(self, **kwargs):
       ...:         super(TestButton, self).__init__(**kwargs)
       ...:         
    
    In [3]: test = TestButton(text='hi')
    
    In [4]: test.text
    Out[4]: 'hi'
    

    您也可以使用自己的属性来执行此操作:

    In [1]: from kivy.uix.widget import Widget
    
    In [2]: from kivy.properties import StringProperty, BooleanProperty, NumericProperty
    
    In [3]: class TestWidget(Widget):
       ...:     name = StringProperty()
       ...:     num = NumericProperty()
       ...:     active = BooleanProperty()
       ...:     
    
    In [4]: test = TestWidget(name='testing', num=12, active=True)
    
    In [5]: test.name, test.num, test.active
    Out[5]: ('testing', 12, True)
    

    (当然,请记住,如果没有构造函数,将自动调用超类的构造函数。)

    有关更多信息,请查看 Kivy 文档的Properties 部分。您可能会发现Events 部分也很有用。

    如果您自己创建了属性,您可以设置默认值,如下所示:

    class TestWidget(Widget):
        prop = StringProperty('default text')
    

    对于继承的属性(如Buttontext):

    class TestButton(Button):
        def __init__(self, **kwargs):
            kwargs.setdefault('text', 'default text')
            super(TestButton, self).__init__(**kwargs)
    

    【讨论】:

    • 这对我不起作用。我的自定义小部件的 init 方法不存在新属性的默认值。例如。对于 ListProperty,返回 [] 而不是定义的默认值。
    • @wackazong 他们应该是。请注意,设置 kv 中的值与设置默认值相同。
    • 啊,那是混乱。仅作记录,如果您需要获取 KV 文件值,则需要延迟初始化方法,如下所述:groups.google.com/d/msg/kivy-users/LuiOykPGcpo/PbMCrYbddKMJ
    猜你喜欢
    • 2012-08-04
    • 1970-01-01
    • 1970-01-01
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多