python-3.x TypeError:模块.__init__()最多接受2个参数(给定3个)

lx0bsm1f  于 2023-03-20  发布在  Python
关注(0)|答案(6)|浏览(285)

我在一个名为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

我哪里做错了?

2nbm6dog

2nbm6dog1#

你的错误发生是因为Object是一个模块,而不是一个类,所以你的继承是有问题的。
将import语句更改为:

from Object import ClassName

和您的类定义设置为:

class Visitor(ClassName):

将类定义更改为:

class Visitor(Object.ClassName):
   etc
0yg35tkg

0yg35tkg2#

即使在“米奇·珀尔斯坦”给出答案并花了3个小时进行调查之后,我还是花了几分钟时间把这个方法应用到我自己的困境中。如果有人和我一样,需要更多的帮助,下面是我的情况。

  • 响应是一个模块
  • Response是responses模块中的基类
  • GeoJsonResponse是从Response派生的新类

初始GeoJsonResponse类:

from pyexample.responses import Response

class GeoJsonResponse(Response):

    def __init__(self, geo_json_data):

看起来很好。没有问题,直到你试着调试这个东西,这是当你得到一堆看起来模糊的错误消息,像这样:
从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”)
这些错误正在尽最大努力给我指出正确的方向,“米奇·珀尔斯坦的回答非常正确,我只花了一分钟就把所有这些都放在了我自己的背景下:
我正在导入***模块***:

from pyexample.responses import Response

当我应该导入***类***时:

from pyexample.responses.Response import Response

希望这对大家有所帮助。(在我看来,现在还为时过早。)

kzmpq1sx

kzmpq1sx3#

from Object import Object

From Class_Name import Class_name

如果对象是.py文件。

1u4esq0p

1u4esq0p4#

您还可以在Python 3.6.1中执行以下操作

from Object import Object as Parent

和您的类定义设置为:

class Visitor(Parent):
o4tp2gmn

o4tp2gmn5#

使用基本import语法的模块与类

这类错误最常见的原因是程序员希望Python像Java一样工作--源文件应该只包含一个以文件命名的“公共”类,并且import提供对该类的访问。
Python不是Java。Python没有访问修饰符关键字;它允许在源文件中放置任意数量的类(包括零个);它还允许在代码的顶层使用类以外的东西;并且对于与源文件共享名称的类,它没有任何特殊行为
类似import Object的代码(假设导入成功)意味着Object将是一个模块的名称,而不是一个类的名称。Python不会对这里的任何类给予特殊处理,即使它与模块同名。在Object.py中定义的一个假设类Object将是**Object模块的Object**属性:Object.Object .
模块不是类,因此不适合作为基类。
假设Object模块定义了一个Object类,要将其用作基类,请选择一个:

  • 使用限定名称引用它:
import Object

class Visitor(Object.Object):
    pass
  • 显式别名:
import Object

my_object = Object.Object
class Visitor(my_object):
    pass
  • 使用from ... import语法将类直接分配给所需的名称:
from Object import Object

class Visitor(Object):
    pass

或者,也可以使用别名as

from Object import Object as my_object

class Visitor(my_object):
    pass

**但是,**使用后一种语法时要小心:

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.pyy.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,但是:

>>> import sys
>>> module = type(sys) # expose the type name
>>> example = module('example', [1, 2, 3])
>>> example.__doc__
[1, 2, 3]

(尽管如果它不是字符串,help(example)将忽略它。)
同样,如果我们试图从其他事物继承:

>>> class example(0): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: int() takes at most 2 arguments (3 given)
>>> class example(()): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: tuple expected at most 1 argument, got 3

如果我们尝试一个对象,它的类型 * do * 接受三个参数作为构造函数,那么这个失败只会被进一步推回:

>>> # 'example' is passed as a buffer to decode,
>>> # ('test',) is passed as an encoding,
>>> # and some dictionary is passed as the error-handling policy.
>>> # All of these values are clearly nonsensical.
>>> class example('test'): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: str() argument 2 must be str, not tuple
yduiuuwa

yduiuuwa6#

在我遇到问题的情况下,当我试图扩展类时,我引用了一个模块。

import logging
class UserdefinedLogging(logging):

如果查看Documentation Info,您会看到“logging”显示为模块。
在这个特定的例子中,我必须简单地继承日志模块,为日志创建一个额外的类。

相关问题