我在Frame
中继承Label
和Tkinter
以自动.pack()
他们(这只是一个用法示例,我的问题与Tkinter没有严格关系)。除标签外,两个类的定义相同:
class Frame(tk.Frame):
def __init__(self, parent, **kwargs):
objparams, packparams = dispatch_parameters(self, **kwargs)
tk.Frame.__init__(self, parent, objparams)
self.pack(packparams)
class Label(tk.Label):
def __init__(self, parent, **kwargs):
objparams, packparams = dispatch_parameters(self, **kwargs)
tk.Label.__init__(self, parent, objparams)
self.pack(packparams)
为了不为这两个类重复相同的代码,我想知道如何通过改变“标签”来重用它。我知道上面的“Frame
”意味着类中的不同事物(一个类名,一个实际的类,......)所以我试图理解是否正确看待某些事情(这是伪代码,试图解释我的观点)
for classname in ["Frame", "Label"]:
class <<classname>>(tk.<<classname>>):
def __init__(self, parent, **kwargs):
objparams, packparams = dispatch_parameters(self, **kwargs)
tk.<<classname>>.__init__(self, parent, objparams)
self.pack(packparams)
这种代码重用案例是否存在pythonic方法?或者我应该坚持一个接一个地定义类,即使代码非常相似?
注1:我认为这个问题与another one, but for objective-c
非常相似注2:我故意省略tkinter
标签,因为我给出的例子只是一般情况的具体实例
答案 0 :(得分:1)
您可以使用type()
function动态创建类:
def class_factory(classname):
base_class = getattr(tk, classname)
def __init__(self, parent, **kwargs):
objparams, packparams = dispatch_parameters(self, **kwargs)
base_class.__init__(self, parent, objparams)
self.pack(packparams)
return type(classname, (base_class, object), {'__init__': __init__})
for classname in ["Frame", "Label"]:
globals()[classname] = class_factory(classname)
当给出3个参数时,type()
函数会从中生成一个类。第一个参数是名称,第二个参数是基类的元组,第三个参数是表示类体的映射。
此处需要object
基础,以便使用Tkinter
模块中的旧式类。
另一种选择是将class
语句的范围放在函数中:
def class_factory(classname):
base_class = getattr(tk, classname)
class CustomClass(base_class):
def __init__(self, parent, **kwargs):
objparams, packparams = dispatch_parameters(self, **kwargs)
base_class.__init__(self, parent, objparams)
self.pack(packparams)
CustomClass.__name__ = classname
return CustomClass
在这里,我们不必混合使用object
基类。