简体   繁体   English

在类继承中使用默认值传递参数的最安全方法是什么?

[英]What is the safest way to pass parameters with defaults in class inheritance?

Suppose I have some Python class: 假设我有一些Python类:

class A:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

And now, I want to define a child class whose y value is set by default, say with value 1. The only change in this new class is this default for y , then I guess this formulation will work 现在,我想定义一个子类,其y值默认设置为,即值为1。在这个新类中,唯一的变化是y默认设置,那么我猜想这种表达方式会起作用

class B(A):
    def __init__(self, **kwargs):
        y = kwargs.pop("y", 1)
        assert y == 1
        super.__init__(y=y, **kwargs)

What is the classic form to pass defaults in inheritance? 在继承中传递默认值的经典形式是什么?

The second code sample won't work. 第二个代码示例将不起作用。 It requires keyword arguments which is surprising compared to the first sample and with assert it requires y == 1 , it doesn't default to it. 它需要关键字参数,这与第一个示例相比是令人惊讶的,并且assert它需要y == 1 ,它不是默认值。 Also super must be called. 还必须调用super

Usual way (with reordering of parameters) is: 通常的方式(对参数进行重新排序)是:

class B(A):
    def __init__(self, x, z, y=1):
        super().__init__(x, y, z)

Alternatively without reordering: 另外,也可以不重新排序:

class B(A):
    def __init__(self, x, yz, z=None):
        if z is None:
            super().__init__(x, 1, yz)
        else:
            super().__init__(x, yz, z)

It depends on what you want. 这取决于您想要什么。 Your current code throws an error if y is anything other than 1 , so it's pointless to make it a parameter at all. 如果y值不是1 ,则当前代码将引发错误,因此将其作为参数完全没有意义。 Just do: 做就是了:

class B(A):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, y=1, **kwargs)

This passes all parameters through to A , whether passed positionally or as keywords, and fixes y to 1 . 这会将所有参数传递给A ,无论是位置传递还是作为关键字传递,并将y固定为1 You'll get an error if you try to pass y to B . 如果尝试将y传递给B则会出错。

Alternatively, if you want y to default to 1 but still be able to supply it as an argument to B : 另外,如果您希望y 默认1但仍然能够将其作为B的参数提供:

class B(A):
    def __init__(self, *args, y=1, **kwargs):
        super().__init__(*args, y=y, **kwargs)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM