【问题标题】:correct way to extend __init__ in python 3 from parent class在 python 3 中从父类扩展 __init__ 的正确方法
【发布时间】:2018-09-24 21:23:33
【问题描述】:

一般问题:将子类完全初始化为其父类但添加单个属性的最简单/“最 Pythonic”的方法是什么?

我的具体问题:我想扩展一个 (Urwid) Edit 对象以包含一个附加属性 my_attribute;我已将原始签名复制到__init__super().__init__,但签名中有一些未定义的参数/常量(LEFTSPACE),我不明白它们是如何在父类。以下是我的(破坏性)类定义和父级 init 方法:

class MyEdit(urwid.Edit):

    def __init__(self, my_attribute, caption="", edit_text="", multiline=False, align=LEFT, wrap=SPACE, allow_tab=False, edit_pos=None, layout=None, mask=None):

        super().__init__(caption="", edit_text="", multiline=False, align=LEFT, wrap=SPACE, allow_tab=False, edit_pos=None, layout=None, mask=None)
        self.my_attribute = []    
        # super().__super.__init__("", align, wrap, layout)

    def my_method(self):
        #some code that modifies my_attribute
        return self.my_attribute




class Edit(Text):
    """
    Text editing widget implements cursor movement, text insertion and
    deletion.  A caption may prefix the editing area.  Uses text class
    for text layout.

    Users of this class to listen for ``"change"`` events
    sent when the value of edit_text changes.  See :func:``connect_signal``.
    """
    # (this variable is picked up by the MetaSignals metaclass)
    signals = ["change"]

    def valid_char(self, ch):
        """
        Filter for text that may be entered into this widget by the user

        :param ch: character to be inserted
        :type ch: bytes or unicode

        This implementation returns True for all printable characters.
        """
        return is_wide_char(ch,0) or (len(ch)==1 and ord(ch) >= 32)

    def selectable(self): return True

    def __init__(self, caption="", edit_text="", multiline=False,
            align=LEFT, wrap=SPACE, allow_tab=False,
            edit_pos=None, layout=None, mask=None):
        """
        :param caption: markup for caption preceeding edit_text, see
                        :class:`Text` for description of text markup.
        :type caption: text markup
        :param edit_text: initial text for editing, type (bytes or unicode)
                          must match the text in the caption
        :type edit_text: bytes or unicode
        :param multiline: True: 'enter' inserts newline  False: return it
        :type multiline: bool
        :param align: typically 'left', 'center' or 'right'
        :type align: text alignment mode
        :param wrap: typically 'space', 'any' or 'clip'
        :type wrap: text wrapping mode
        :param allow_tab: True: 'tab' inserts 1-8 spaces  False: return it
        :type allow_tab: bool
        :param edit_pos: initial position for cursor, None:end of edit_text
        :type edit_pos: int
        :param layout: defaults to a shared :class:`StandardTextLayout` instance
        :type layout: text layout instance
        :param mask: hide text entered with this character, None:disable mask
        :type mask: bytes or unicode

        >>> Edit()
        <Edit selectable flow widget '' edit_pos=0>
        >>> Edit("Y/n? ", "yes")
        <Edit selectable flow widget 'yes' caption='Y/n? ' edit_pos=3>
        >>> Edit("Name ", "Smith", edit_pos=1)
        <Edit selectable flow widget 'Smith' caption='Name ' edit_pos=1>
        >>> Edit("", "3.14", align='right')
        <Edit selectable flow widget '3.14' align='right' edit_pos=4>
        """

        self.__super.__init__("", align, wrap, layout)
        self.multiline = multiline
        self.allow_tab = allow_tab
        self._edit_pos = 0
        self.set_caption(caption)
        self.set_edit_text(edit_text)
        if edit_pos is None:
            edit_pos = len(edit_text)
        self.set_edit_pos(edit_pos)
        self.set_mask(mask)
        self._shift_view_to_cursor = False

【问题讨论】:

  • 我看不出这段代码有任何问题。有错误吗?
  • @Primusa name 'LEFT' is not defined
  • @Primusa 我认为这必须从父类 super 设置,但我不知道如何继承两代 :)
  • 那么,你定义了吗?这段代码中确实没有定义。不过,这似乎与继承无关。 (此外,您的 Edit 课程似乎完全不相关,所以我不知道您为什么发布它。)
  • 但 LEFT 在 urwid 模块中定义的。它没有在您的模块中定义。如果你想在你的中使用它,你需要引用urwid.LEFT 或显式导入它。同样,这与 Python 作用域有关,与继承无关。

标签: python python-3.x oop initialization urwid


【解决方案1】:

你不使用这些变量,所以只是盲目地传递它们。

class MyEdit(urwid.Edit):

    def __init__(self, my_attribute, *args, **kw):
        super().__init__(*args, **kw)
        self.my_attribute = []    

    def my_method(self):
        #some code that modifies my_attribute
        return self.my_attribute

【讨论】:

  • 您可以总是使用*args**kwargs 来复制父签名吗?
  • 大多数情况下......如果您正在执行多重继承,那么您必须担心哪些数据应该进入哪个初始化程序。但它通常用于您不想在父级中挖掘默认参数的特定用例。
猜你喜欢
  • 2022-01-08
  • 1970-01-01
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多