0

我正在尝试学习python中的继承。我将“Course”类写为“AdvacedCourse”类的超类,如下所示。

class Course(object):
     def __init__(self, crsName ="python", duration=45):
         self.crsName = crsName
         self.duration = 25

子类是:

import Course
class AdvancedCourse (Course):    
    def __init__(self, crsName ="python", duration=45):
        self.crsName = "java"
        self.duration = 25

但是我遇到了一个错误:

    class AdvancedCourse (Course):
TypeError: module.__init__() takes at most 2 arguments (3 given)

有什么建议么?

4

3 回答 3

3

这是导入问题,而不是继承问题。Course是模块:你需要继承自Course.Course. (不过,在 Python 中,我们通常用小写命名模块)。

于 2013-07-05T12:23:30.470 回答
1

注意:我只是将其作为答案,因为 ElmoVanKielmo 建议这样做。它绝对不应该是公认的答案,因为它只会让新手感到困惑……但也许对其他人来说会很有趣。

正如丹尼尔罗斯曼的回答所解释的那样,import Course这意味着这Course是一个模块,并且Course.Course是您想要的课程。

那么,当您尝试从模块继承时会发生什么?

在 Python 中,类是对象,就像其他任何东西一样。一个类的类型(你可以通过打印出来看到type(AdvancedCourse))通常是type,但是你可以通过设置一个元类来指定一个不同的类型。当你从一个超类继承时,如果你没有指定一个元类,你会得到你的超类的元类。所以,当你这样做时:

import Course
class AdvancedCourse(Course):

…你是说你的元类是type(Course)——也就是说,module.*

正如创建实例意味着调用类的 一样__init__,创建类意味着调用元类的__init__。参数,除此之外self(这里是一个类,当然不是实例,因此通常命名cls而不是self)是类名、基类列表、方法字典和其他属性。所以,这个定义:

class AdvancedCourse(Course):
    pass

... 尝试module通过调用module.__init__(cls, 'AdvancedCourse', (Course,), {}).**来初始化对象

当然模块也只是对象,所以它们也有一个__init__,但它们的参数只是self,名称和文档字符串。所以,你传递的参数太多了。

您实际上只是在这里走运;如果module并且type碰巧在它们的构造函数中采用相同数量的参数,你最终会得到一些非常奇怪的东西,在某些方面表现得有点像一个类,但在其他方面却不是,从而导致各种微妙的错误。


如果你想在交互式解释器中使用它,试试这个:

>>> class meta(type):
...     def __init__(self, name, bases, d):
...         print('{}\n{}\n{}\n{}\n'.format(self, name, bases, d))
...         super(meta, self).__init__(name, bases, d)
>>> class Silly(metaclass=meta):
...      __metaclass__=meta
<class '__main__.Silly'>
Silly
()
{'__module__': '__main__', '__qualname__': 'Silly', '__metaclass__': <class '__main__.meta'>}
>>> class Sillier(Silly):
...     pass
<class '__main__.Sillier'>
Sillier
(<class '__main__.Silly'>,)
{'__module__': '__main__', '__qualname__': 'Sillier'}

在 Python 2.x 中,您不希望metaclass=meta在类头中出现;你可以放在object那里。在 3.x 中,您不需要__metaclass__=meta在体内;你可以放在pass那里。


*module是内置函数中无法通过名称访问的“隐藏”类型之一,但您可以将其作为types.ModuleType,或者仅通过导入某些内容并使用type(Course).

** 实际上,即使是一个空类,它的字典中也有几个成员。例如,在 Python 3.3 中,总是至少有一个__module__属性和一个__qualname__属性。

于 2013-07-05T13:19:04.460 回答
1

我假设该类Course在另一个模块Course.py中。
然后你应该用from Course import Course. @Daniel 是对的 - 你应该在文件中有模块course.py(小写)并且 import 语句将是from course import Course.

于 2013-07-05T12:30:18.063 回答