我在一个名为Object.py
的文件中定义了一个类,当我试图从另一个文件中的这个类继承时,调用构造函数会抛出一个异常:
TypeError: module.__init__() takes at most 2 arguments (3 given)
这是我的代码:
import Object
class Visitor(Object):
pass
instance = Visitor() # this line throws the exception
我哪里做错了?
我在一个名为Object.py
的文件中定义了一个类,当我试图从另一个文件中的这个类继承时,调用构造函数会抛出一个异常:
TypeError: module.__init__() takes at most 2 arguments (3 given)
这是我的代码:
import Object
class Visitor(Object):
pass
instance = Visitor() # this line throws the exception
我哪里做错了?
6条答案
按热度按时间2nbm6dog1#
你的错误发生是因为
Object
是一个模块,而不是一个类,所以你的继承是有问题的。将import语句更改为:
和您的类定义设置为:
或
将类定义更改为:
0yg35tkg2#
即使在“米奇·珀尔斯坦”给出答案并花了3个小时进行调查之后,我还是花了几分钟时间把这个方法应用到我自己的困境中。如果有人和我一样,需要更多的帮助,下面是我的情况。
初始GeoJsonResponse类:
看起来很好。没有问题,直到你试着调试这个东西,这是当你得到一堆看起来模糊的错误消息,像这样:
从pyexample.responses导入GeoJsonResponse..\pyexample\responses\GeoJsonResponse.py:12:在(模块)类GeoJsonResponse(响应)中:
E类型错误:module()最多接受2个参数(给定3个)
===============================错误============
________________错误收集测试/test_geojson.py __________________
测试_地理位置.py:2:在(模块)中从pypexample.responses导入GeoJsonResponse..\pypexample\responses \GeoJsonResponse.py:12:in(模块)
类GeoJson响应(响应):E类型错误:module()最多接受2个参数(给定3个)
错误:未找到:\PyExample\测试\测试地理对象.py::测试地理对象::测试API响应
C:\Python 37\库\站点包\枚举__初始化.py:163
(no在[]中的任何一个中命名“PyExample\ tests\test_geojson.py::TestGeoJson::test_API_response”)
这些错误正在尽最大努力给我指出正确的方向,“米奇·珀尔斯坦的回答非常正确,我只花了一分钟就把所有这些都放在了我自己的背景下:
我正在导入***模块***:
当我应该导入***类***时:
希望这对大家有所帮助。(在我看来,现在还为时过早。)
kzmpq1sx3#
或
如果对象是
.py
文件。1u4esq0p4#
您还可以在Python 3.6.1中执行以下操作
和您的类定义设置为:
o4tp2gmn5#
使用基本
import
语法的模块与类这类错误最常见的原因是程序员希望Python像Java一样工作--源文件应该只包含一个以文件命名的“公共”类,并且
import
提供对该类的访问。Python不是Java。Python没有访问修饰符关键字;它允许在源文件中放置任意数量的类(包括零个);它还允许在代码的顶层使用类以外的东西;并且对于与源文件共享名称的类,它没有任何特殊行为。
类似
import Object
的代码(假设导入成功)意味着Object
将是一个模块的名称,而不是一个类的名称。Python不会对这里的任何类给予特殊处理,即使它与模块同名。在Object.py
中定义的一个假设类Object
将是**Object
模块的Object
**属性:Object.Object
.模块不是类,因此不适合作为基类。
假设
Object
模块定义了一个Object
类,要将其用作基类,请选择一个:from ... import
语法将类直接分配给所需的名称:或者,也可以使用别名
as
:**但是,**使用后一种语法时要小心:
from ... import
语法对于类似
from x.y import z
的导入,有两种可能性:x
是一个包,y
是该包中的一个模块,而z
是该模块的某个属性(同样,类不是特殊的;z
可以是诸如整数之类的任何值)-即,在模块的顶层运行代码时留下的全局变量。x
是一个封装,y
是该封装的子封装,而z
是该子封装中的模块。(Python将包表示为一种模块,因此实际上只有一个区别:无论是X1 M22 N1 X艾德X1 M23 N1 X,指定的包/模块也是模块还是其某个组件)。
当然,会出现哪种结果取决于
x
包的内容,而x
包的内容又取决于 *x
是在哪里找到的。包、子包、模块和属性重用一个公共名称,极大地增加了混淆的可能性(不幸的是,Python标准库在一些地方这样做,特别是with datetime)。例如,给定
x.py
和y.py
在同一个目录中,其中x.py
实现了x
类,可以在y.py
代码中写入from x import x
,期望这表示类。但是,如果这个“相同目录”碰巧命名为x
,如果 * 父目录 * 是搜索绝对导入的路径,则from x import x
将表示 * 模块 *(从x.py
源文件创建,导入from
表示x
文件夹的包)。As long as the package root is on the module search path,使用相对导入很容易避免这个问题。继续这个例子,在
y.py
中,from .x import x
明确表示类,from . import x
明确表示兄弟模块。我们不需要推理sys.path
的内容,或者当写代码时,关于import
运行时当前工作目录将是什么(在sys.path
包括相对路径的情况下);我们只需要确保代码正确运行(使得X1 M43 N1 X模块正确设置其X1 M44 N1 X)。为什么出现此特定错误消息?
我想对“所以你的遗产是扭曲的”这一主张补充一些细节。
出现这个问题的原因是代码试图使用某个不是类型的东西作为基类,回想一下,在Python中,类本身就是对象,每个对象都有某种类型(也就是说,它是哪个类的示例)。
当Python处理一个普通
class
定义的调用时,它会收集内容并调用内置的type
(不是函数,而是对type
类的构造函数的调用,这个类定义了类的默认类型--包括它自己),它会被传递三个参数:作为字符串的类名(这里为X1 M48 N1 X)、新类的基类元组(这里为X1 M49 N1 X-即元组中的模块本身)、以及要为新类设置的属性字典(其将包括类主体内定义的所有方法和类变量,加上一些特殊的东西,如'__module__'
和'__qualname__'
)。然而,对
type
的调用并不是硬编码的,相反,Python寻找基类的类型 *,以确定使用什么元类(type
只是一个可能的元类),通过这样做,Python确保派生类具有与基类相同的元类。当示例代码运行时,Python将查找
Object
的类型,并发现它是一个模块,因此,它将尝试创建一个新的类型,命名为Visitor
,以Object
作为它的基,它将尝试创建一个新的 module,使用module
类型的构造函数(默认情况下没有赋值为内置函数)。碰巧的是,这个构造函数没有文档化(模块对象只能由
import
系统创建,而不能直接由用户创建),但它需要一个或两个参数:新模块的名称(作为字符串),以及可选的用于docstring的值(模块的__doc__
属性)-顺便提一下,它没有进行类型检查;它应该是字符串或None
,但是:(尽管如果它不是字符串,
help(example)
将忽略它。)同样,如果我们试图从其他事物继承:
如果我们尝试一个对象,它的类型 * do * 接受三个参数作为构造函数,那么这个失败只会被进一步推回:
yduiuuwa6#
在我遇到问题的情况下,当我试图扩展类时,我引用了一个模块。
如果查看Documentation Info,您会看到“logging”显示为模块。
在这个特定的例子中,我必须简单地继承日志模块,为日志创建一个额外的类。