python 中的构造函数专业化

发布于 2024-07-30 01:53:17 字数 1338 浏览 5 评论 0原文

类层次结构和构造函数是相关的。 子类的参数需要传递给其父类。

因此,在 Python 中,我们最终会得到这样的结果:

class Parent(object):
    def __init__(self, a, b, c, ka=None, kb=None, kc=None):
        # do something with a, b, c, ka, kb, kc

class Child(Parent):
    def __init__(self, a, b, c, d, e, f, ka=None, kb=None, kc=None, kd=None, ke=None, kf=None):
        super(Child, self).__init__(a, b, c, ka=ka, kb=kb, kc=kc)
        # do something with d, e, f, kd, ke, kf

想象一下有十几个子类和大量参数。 添加新参数变得非常繁琐。

当然,可以完全放弃命名参数并使用 *args 和 **kwargs,但这会使方法声明变得不明确。

Python (2.6) 中是否有一种模式可以优雅地处理这个问题?

我所说的“优雅”是指我想减少参数出现的次数。 a、b、c、ka、kb、kc 都出现 3 次:在 Child 构造函数中、在对 Parent 的 super() 调用中以及在 Parent 构造函数中。

理想情况下,我想为父级的 init 指定一次参数,并在子级的 init 中仅指定附加参数。

我想做这样的事情:

class Parent(object):
    def __init__(self, a, b, c, ka=None, kb=None, kc=None):
        print 'Parent: ', a, b, c, ka, kb, kc

class Child(Parent):
    def __init__(self, d, e, f, kd='d', ke='e', kf='f', *args, **kwargs):
        super(Child, self).__init__(*args, **kwargs)
        print 'Child: ', d, e, f, kd, ke, kf

x = Child(1, 2, 3, 4, 5, 6, ka='a', kb='b', kc='c', kd='d', ke='e', kf='f')

不幸的是,这不起作用,因为 4、5、6 最终分配给 kd、ke、kf。

是否有一些优雅的 python 模式可以完成上述任务?

Class hierarchies and constructors are related. Parameters from a child class need to be passed to their parent.

So, in Python, we end up with something like this:

class Parent(object):
    def __init__(self, a, b, c, ka=None, kb=None, kc=None):
        # do something with a, b, c, ka, kb, kc

class Child(Parent):
    def __init__(self, a, b, c, d, e, f, ka=None, kb=None, kc=None, kd=None, ke=None, kf=None):
        super(Child, self).__init__(a, b, c, ka=ka, kb=kb, kc=kc)
        # do something with d, e, f, kd, ke, kf

Imagine this with a dozen child classes and lots of parameters. Adding new parameters becomes very tedious.

Of course one can dispense with named parameters completely and use *args and **kwargs, but that makes the method declarations ambiguous.

Is there a pattern for elegantly dealing with this in Python (2.6)?

By "elegantly" I mean I would like to reduce the number of times the parameters appear. a, b, c, ka, kb, kc all appear 3 times: in the Child constructor, in the super() call to Parent, and in the Parent constructor.

Ideally, I'd like to specify the parameters for Parent's init once, and in Child's init only specify the additional parameters.

I'd like to do something like this:

class Parent(object):
    def __init__(self, a, b, c, ka=None, kb=None, kc=None):
        print 'Parent: ', a, b, c, ka, kb, kc

class Child(Parent):
    def __init__(self, d, e, f, kd='d', ke='e', kf='f', *args, **kwargs):
        super(Child, self).__init__(*args, **kwargs)
        print 'Child: ', d, e, f, kd, ke, kf

x = Child(1, 2, 3, 4, 5, 6, ka='a', kb='b', kc='c', kd='d', ke='e', kf='f')

This unfortunately doesn't work, since 4, 5, 6 end up assigned to kd, ke, kf.

Is there some elegant python pattern for accomplishing the above?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情深如许 2024-08-06 01:53:17

好吧,我能看到的唯一解决方案是使用列出的变量以及 *args 和 **kwargs 的混合,如下所示:

class Parent(object):
    def __init__(self, a, b, c, ka=None, kb=None, kc=None):
        pass

class Child(Parent):
    def __init__(self, d, e, f, *args, kd=None, ke=None, kf=None, **kwargs):
        Parent.__init__(self, *args, **kwargs)
        pass

这样,您可以看到每个类需要哪些参数,但不必重新输入它们。

需要注意的一件事是,当它变成 (d, e, f, a, b, c) 时,您会丢失所需的顺序 (a, b, c, d, e, f)。 我不确定是否有办法在其他非命名参数之前添加 *args 。

Well, the only solution I could see is using a mixture of listed variables as well as *args and **kwargs, as such:

class Parent(object):
    def __init__(self, a, b, c, ka=None, kb=None, kc=None):
        pass

class Child(Parent):
    def __init__(self, d, e, f, *args, kd=None, ke=None, kf=None, **kwargs):
        Parent.__init__(self, *args, **kwargs)
        pass

This way, you could see which parameters are required by each of the classes, but without having to re-type them.

One thing to note is that you lose your desired ordering (a, b, c, d, e, f) as it becomes (d, e, f, a, b, c). I'm not sure if there's a way to have the *args before the other non-named parameters.

无戏配角 2024-08-06 01:53:17

我尝试将参数分组到它们自己的对象中,例如,而不是传递
sourceDirectory、targetDirectory、temporaryDirectory、serverName、serverPort,我有一个
DirectoryContext 和 ServerContext 对象。

如果上下文对象开始拥有更多
它可能导致此处中提到的策略对象的行为或逻辑。

I try to group the parameters into their own objects, e.g, instead of passing
sourceDirectory, targetDirectory, temporaryDirectory, serverName, serverPort, I'd have a
DirectoryContext and ServerContext objects.

If the context objects start having more
behavior or logic it might lead to the strategy objects mentioned in here.

鸵鸟症 2024-08-06 01:53:17

无论参数命名如何,“十几个子类和大量参数”听起来都是一个问题。

我怀疑一点重构可以剥离一些 Strategy 对象,这些对象可以简化这个层次结构并使超级复杂的构造函数消失。

"dozen child classes and lots of parameters" sounds like a problem irrespective of parameter naming.

I suspect that a little refactoring can peel out some Strategy objects that would simplify this hierarchy and make the super-complex constructors go away.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文