Python 3扩展父类__init__的规范方式及子类初始化实践疑问
如何以Pythonic方式扩展Urwid的Edit类并添加自定义属性
嘿,这个问题我之前在扩展Urwid组件的时候也遇到过,刚好可以给你讲清楚~
首先说通用的Python最佳实践:永远不要硬复制父类的__init__签名,这既麻烦又容易出错(比如父类更新参数后你的代码就失效了)。最Pythonic的方式是用super().__init__(*args, **kwargs)来传递所有父类需要的参数,然后在这个调用的前后处理你自己的自定义属性。
回到你扩展Urwid Edit类的场景:你碰到的LEFT、SPACE这些其实是Urwid模块定义的常量(比如urwid.LEFT、urwid.SPACE),但你完全不需要在子类里硬写这些参数——用*args和**kwargs就能完美绕过这个问题,把所有父类需要的参数原封不动传过去。
具体实现代码
这里给你两种常见的实现方式,根据你的需求选:
方式1:给自定义属性设置默认值
如果my_attribute有默认值,不需要用户实例化时传入,可以这么写:
import urwid class MyEdit(urwid.Edit): def __init__(self, *args, **kwargs): # 先让父类完成所有初始化逻辑,传递所有收到的参数 super().__init__(*args, **kwargs) # 初始化你的自定义属性 self.my_attribute = "默认值"
方式2:允许用户实例化时传入自定义属性
如果想让用户在创建MyEdit对象时指定my_attribute,需要先从kwargs中取出这个参数,再把剩下的参数传给父类(避免父类收到不认识的参数报错):
import urwid class MyEdit(urwid.Edit): def __init__(self, *args, **kwargs): # 从kwargs中取出自定义属性,第二个参数是默认值(如果用户没传就用这个) self.my_attribute = kwargs.pop('my_attribute', "默认值") # 把剩下的所有参数传给父类初始化 super().__init__(*args, **kwargs)
为什么这种方式更好?
- 兼容性强:不管Urwid的Edit类以后怎么修改
__init__的参数,你的子类都能正常工作,不用跟着改签名。 - 代码简洁:不用去查父类的所有参数和常量,省了很多麻烦。
- 符合Python风格:遵循了DRY(Don't Repeat Yourself)原则,避免重复代码。
举个实例化的例子:
# 使用默认的my_attribute edit1 = MyEdit("请输入内容:") # 自定义my_attribute的值 edit2 = MyEdit("请输入密码:", my_attribute="password_input")
内容的提问来源于stack exchange,提问作者anon01
相关产品推荐
相关产品推荐

