Python 标准构造函数有多余信息时的第二个构造函数

Python 标准构造函数有多余信息时的第二个构造函数,python,constructor,Python,Constructor,我有以下情况: class Foo: def __init__(self, O): self.a = O.some_attr.calc_a() self.b = O.some_other_attr.calc_b() 请注意,O不能从a和b重建。现在,我还想通过传递a和b直接初始化Foo,但我只想在内部进行初始化,标准方法应该是传递O 我知道我可以做像这样的事情 class Foo: def __init__(self, a, b):

我有以下情况:

class Foo:
    def __init__(self, O):
         self.a = O.some_attr.calc_a()
         self.b = O.some_other_attr.calc_b()
请注意,
O
不能从
a
b
重建。现在,我还想通过传递
a
b
直接初始化
Foo
,但我只想在内部进行初始化,标准方法应该是传递
O

我知道我可以做像这样的事情

class Foo:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    @classmethod
    def from_O(cls, O):
        return cls(O.some_attr.cal_a(), O.some_other_attr.cal_b())
class _Foo:
    def __init__(self, a, b):
        self.a = a
        self.b = b

class Foo(_Foo):
    def __init__(self, O):
        super().__init__(O.some_attr.cal_a(), O.some_other_attr.cal_b())
但这有一个缺点,即标准调用现在变得更加麻烦
Foo.from_O(O)

换句话说,当
O
不能从
a
b
重建时,我如何从
b(a,b)
获得
Foo(O)
? 我可以有一个避免调用
\uuuu init\uuuu
的classmethod吗

(注意:我正在寻找一种“干净”的方法来做到这一点。我知道我可以剖析参数列表或做类似的事情

class Foo:
    def __init__(self, a, b):
        self.a = a
        self.b = b

    @classmethod
    def from_O(cls, O):
        return cls(O.some_attr.cal_a(), O.some_other_attr.cal_b())
class _Foo:
    def __init__(self, a, b):
        self.a = a
        self.b = b

class Foo(_Foo):
    def __init__(self, O):
        super().__init__(O.some_attr.cal_a(), O.some_other_attr.cal_b())

但是这似乎是一个相当尴尬的解决方案。)

您可以将
O
a
b
所有可选参数设置为相同的
\uuuu init\uuuuu
方法,并区分是否给出了
O

class Foo:
    def __init__(self, O=None, a=None, b=None):
         if O is not None:
             self.a = O.some_attr.calc_a()
             self.b = O.some_other_attr.calc_b()
             # ignore a and b
         else:
             if a is None or b is None:
                 raise TypeError("If O is not given, a and b cannot be None")
             self.a = a
             self.b = b
用法:

# from O
foo_from_O = Foo(O)

# from a, b
foo_from_a_b_1 = Foo(None, 'a', 'b')
foo_from_a_b_2 = Foo(a='a', b='b')

classmethod
使用
from
有些东西很常见,很明显,您实际上想要使用某种类型的对象<代码>\uuuu init\uuuu用于直接值。。。把这两者混在一起会很奇怪。。。你的“我知道我可以做一些类似的事情”方法是一种类似于python的方法,如果你想从一个源直接混合
a
,从一个计算源混合
b
,如果同时通过这两个源,会发生什么,等等),这实际上更令人困惑。谢谢。但我恐怕这正是“剖析论证清单”所指的内容。。。你所尝试的就是最好的方法。。。否则,你只会做一些临时的事情