Multiple constructors in python, using inheritance
我有一个类abstractdatahandle(它的init方法)和一个类分类器。我希望在分类器中有两个构造函数,比如Java。一个继承了它的超类,一个全新的。
它类似于(但我打算"保留"这两个构造函数):
1 2 3 4 5 6 7 8 | class AbstractDataHandle(): def __init__(self, elements, attributes, labels): self._load(elements, attributes, labels) class Classifier(AbstractDataHandle): def __init__(self, classifier="LinearSVC", proba=False): self._fit(classifier, proba) |
一个类中可以有两个构造函数吗?如果是,我可以从一个超类继承一个构造函数,并添加一个新的吗?
提前谢谢。
一个类中不能有两个构造函数。
必须将构造函数命名为
有几种方法可以解决这个问题。
使用
1 2 3 4 5 6 7 8 9 10 11 12 | class Breakfast(object): @classmethod def from_eggs(cls, eggs): obj = cls() obj.spam, obj.eggs = 5, eggs return obj @classmethod def from_spam_and_eggs(cls, spam, eggs): obj = cls() obj.spam, obj.eggs = spam, eggs return obj |
标准库中的一个简单示例是
使用默认值、仅关键字和/或变量参数来生成可通过不同方式调用的单个构造函数:
1 2 3 | class Breakfast(object): def __init__(self, eggs=0, spam=5): self.spam, self.eggs = spam, eggs |
创建每个子类都有不同的构造函数:
1 2 3 4 5 6 7 8 9 10 | class Breakfast(object): pass class HealthyBreakfast(object): def __init__(self, spam): self.spam, self.eggs = spam, 0 class NormalBreakfast(object): def __init__(self, spam, eggs): self.spam, self.eggs = spam, eggs |
在任何这些情况下,您都可以将共性分解为单个"基"初始值设定项。例如:
1 2 3 4 5 6 7 | class Breakfast(object): def __init__(self, eggs, spam): self.spam, self.eggs = spam, eggs class HealthyBreakfast(object): def __init__(self, spam): super(HealthyBreakfast, self).__init__(0, spam) |
当然,在任何情况下,早餐都不可能没有垃圾邮件。
您可以使用类方法,它作为工厂方法工作。对于多个构造函数来说,这是最好的方法。第一个参数"cls"是类本身,而不是实例,因此类方法中的cls("truck")调用类car的构造函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Car(object): def __init__(self, type='car'): self.car_type = type @classmethod def Truck(cls): return cls('Truck') @classmethod def Sport(cls): return cls('Sport') @classmethod def Van(cls): return cls('Van') |
然后用这种方式调用工厂方法:
1 | mycar = Car.Sport() |
在公认的答案中有一些方法,但我认为这个方法相当灵活。这很复杂,但很灵活。
当类被插入时,init调用一个方法并传递一个字符串参数(从实例化中获得)。该函数使用条件调用正确的"构造函数"函数来初始化您的值,假设您有不同的可能起始值集。
如果需要提供其他参数(例如,可能只有在运行时才有值),可以使用init()中的默认值来允许可选参数,并像通常那样初始化init中的参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | class MyClass: def __init__(self,argsSet1, otherAttribute="Assigning this default value to make this other argument optional",): self.selectArgSet(argsSet1) self.otherAttribute = otherAttribute print otherAttribute def selectArgSet(self,ArgSet1): if ArgSet1 =="constructorArgSet1": self.constructorArgSet1() elif ArgSet1 =="constructorArgSet2": self.constructorArgSet2() def constructorArgSet1(self): print"Use this method as Constructor 1" self.variable1 ="Variable1 value in Constructor 1" self.variable2 ="Variable2 value in Constructor 1" print self.variable1 print self.variable2 def constructorArgSet2(self): print"Use this method as Constructor 2" self.variable1 ="Variable1 value in Constructor 2" self.variable2 ="Variable2 value in Constructor 2" print self.variable1 print self.variable2 myConstructor_1_Instance = MyClass("constructorArgSet1") myConstructor_2_Instance = MyClass("constructorArgSet2","You can still initialize values normally") |
其输出为:
Use this method as Constructor 1
Variable1 value in Constructor 1
Variable2 value in Constructor 1
Assign default value to make this other argument optional
Use this method as Constructor 2
Variable1 value in Constructor 2
Variable2 value in Constructor 2
You can still initialize values normally