如何向现有Python类添加方法和参数

时间:2014-11-14 08:54:16

标签: python list class methods

我有一个函数返回一个根据函数选项准备的特殊列表:

def Matrix(
    numberOfColumns = 3,
    numberOfRows = 3,
    element = 0.0
    ):
    matrix = []
    for column in range(numberOfColumns):
        matrix.append([element] * numberOfRows)
    return(matrix)

我想基于现有的类list创建一个新类,并添加各种方法和各种参数,以创建一个特殊的列表,就像上面函数中显示的方式一样。我可以创建这个新类,并以如下方式添加方法:

class Matrix(list):
    def __init__(self, *args):
        list.__init__(self, *args)
    def printout(self):
        return("PRINTOUT")

我不确定如何向新类添加新参数。类list接受一个位置参数,我不确定如何以合理的方式向类中添加更多。

具体来说,我可能希望能够以如下方式创建新类的实例:

a = Matrix(numberOfColumns = 3, numberOfRows = 2)

我按以下方式设置课程:

class Matrix(list):

    def __init__(
        self,
        numberOfColumns = 3,
        numberOfRows = 3,
        element = 0.0,
        *args
        ):
        self.numberOfColumns = numberOfColumns
        self.numberOfRows = numberOfRows
        super().__init__(self, *args)
    def printout(self):
        return("PRINTOUT")

当我以下列方式实例化时:

a = Matrix(numberOfColumns = 3)

我遇到以下错误:

TypeError: super() takes at least 1 argument (0 given)

当我以下列方式实例化时:

a = Matrix("1", numberOfColumns = 3)

我遇到以下错误:

TypeError: __init__() got multiple values for keyword argument 'numberOfColumns'

我哪里错了?

1 个答案:

答案 0 :(得分:1)

首先,您不应将函数命名为Matrix

您可以像在其他所有类中一样向该类添加参数,只需将其添加到__init__方法中,然后将其他方法添加到list.__init__

class Matrix(list):
    def __init__(self, numberOfColumns, numberOfRows, *args):
        super().__init__(self, *args)
        self.numberOfColumns = numberOfColumns
        self.numberOfRows = numberOfRows

    def printout(self):
        return("PRINTOUT")

在这里,您说Matrix构造函数采用两个位置参数(numberOfColumnsnumberOfRows)以及未知数量的其他位置参数。然后,您将这些额外的参数(以及那些参数)添加到list的构造函数中,然后将numberOfColumnsnumberOfRows作为属性添加到您的类中。

编辑之后,您似乎也想在构造函数中使用一些关键字参数,这些参数应该在每个位置参数之后定义,如下所示:

    def __init__(self, *args, numberOfColumns = 3, numberOfRows = 3, element = 0.0):
        super().__init__(self, *args)
        self.numberOfColumns = numberOfColumns
        self.numberOfRows = numberOfRows
        self.element = element # I guess you also want `element` to be an attribute of your class

了解错误

要理解您从编辑中获得的错误(TypeError: __init__() got multiple values for keyword argument 'numberOfColumns'),让我们使用一个简短的示例函数:

>>> def foo(positional, kw='default', *args):
...     print(positional, kw, *args)
...
>>> foo(1)
1 default
>>> foo(1, 2)
1 2
>>> foo(1, 2, 3)
1 2 3
>>> foo(1, kw='bar')
1 bar
>>> foo(1, 2, kw='bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() got multiple values for keyword argument 'kw'

调用foo时给出的参数是从左到右分配的,即使参数是关键字参数。因此,在致电foo(1, 2)时,您将1分配给positional,将2分配给kw,并在致电foo(1, 2, kw='bar')时给予kw两个值:一个按位置(2),另一个按关键字('bar')。

foo更好地定义如下:

>>> def foo(positional, *args, kw='default'):
...     print(positional, kw, *args)
...
>>> foo(1)
1 default
>>> foo(1, 2)
1 default 2
>>> foo(1, 2, 3)
1 default 2 3
>>> foo(1, kw='bar')
1 bar
>>> foo(1, 2, kw='bar')
1 bar 2

这样您就不必担心错误地按位置分配关键字参数。

供参考:some explanation on *args and **kwargs