为什么我会收到“TypeError:缺少 1 个必需的位置参数:'self'”?

问题描述 投票:0回答:10

我有一些代码,例如:

class Pump:    
    def __init__(self):
        print("init")

    def getPumps(self):
        pass

p = Pump.getPumps()
print(p)

但是我收到如下错误:

Traceback (most recent call last):
  File "C:\Users\Dom\Desktop\test\test.py", line 7, in <module>
    p = Pump.getPumps()
TypeError: getPumps() missing 1 required positional argument: 'self'

为什么

__init__
似乎没有被调用,这个异常是什么意思?我的理解是
self
会自动传递给构造函数和方法。我在这里做错了什么?

python constructor typeerror positional-argument
10个回答
575
投票

要使用该类,首先创建一个实例,如下所示:

p = Pump()
p.getPumps()

完整示例:

>>> class TestClass:
...     def __init__(self):
...         print("init")
...     def testFunc(self):
...         print("Test Func")
... 
>>> testInstance = TestClass()
init
>>> testInstance.testFunc()
Test Func

99
投票

您需要先初始化它:

p = Pump().getPumps()

11
投票

向方法添加

@classmethod
装饰器可以像
Pump.getPumps()
一样调用它。

类方法接收类作为隐式第一个参数,就像实例方法接收实例一样。

class Pump:
    def __init__(self):
        print("init")

    @classmethod
    def getPumps(cls):
        pass

8
投票

Python 中的

self
关键字类似于 C++ / Java / C# 中的
this
关键字。

在 Python 2 中,它是由编译器隐式完成的(是的,Python 在内部进行编译)。 只是在 Python 3 中你需要在构造函数和成员函数中显式地提及它。示例:

class Pump():
    # member variable
    # account_holder
    # balance_amount

    # constructor
    def __init__(self,ah,bal):
        self.account_holder = ah
        self.balance_amount = bal

    def getPumps(self):
        print("The details of your account are:"+self.account_number + self.balance_amount)

# object = class(*passing values to constructor*)
p = Pump("Tahir",12000)
p.getPumps()

6
投票

您还可以通过过早采用 PyCharm 的建议来注释方法 @staticmethod 来获得此错误。删除注释。


2
投票

记住2点

  1. 定义类时不要()括号将类名括起来。

    class Pump:    
    def __init__(self):
    
  2. 此外,在按对象实例化类时,不要忘记使用 () 括号。因为只有这样才会显示上述错误。

  • 如果您想在不实例化对象的情况下调用方法,然后内联实例化

    Pump().getPumps()

  • 但理想的最佳实践是使用短键实例化对象,然后使用实例化的对象来调用类的方法,例如

     p = Pump()
     p.getPumps()
    

1
投票

如果跳过对象声明的括号(拼写错误),则会发生此错误。

# WRONG! will result in TypeError: getPumps() missing 1 required positional argument: 'self'
p = Pump
p.getPumps()

不要忘记 Pump 对象的括号

# CORRECT!
p = Pump()
p.getPumps()

1
投票

我在下面遇到了同样的错误:

TypeError:test() 缺少 1 个必需的位置参数:'self'

实例方法

self
时,那么我直接通过类名调用它,如下所示:

class Person:
    def test(self): # <- With "self" 
        print("Test")

Person.test() # Here

并且,当静态方法

self
时,然后我通过对象或直接通过类名调用它,如下所示:

class Person:
    @staticmethod
    def test(self): # <- With "self" 
        print("Test")

obj = Person()
obj.test() # Here

# Or

Person.test() # Here

所以,我用对象调用了实例方法,如下所示:

class Person:
    def test(self): # <- With "self" 
        print("Test")

obj = Person()
obj.test() # Here

并且,我从静态方法中删除了

self
,如下所示:

class Person:
    @staticmethod
    def test(): # <- "self" removed 
        print("Test")

obj = Person()
obj.test() # Here

# Or

Person.test() # Here

然后,错误就解决了:

Test

详细地,我在我的答案中解释了什么是Python中的“实例方法”?,并解释了@staticmethod@classmethod我的答案中,@classmethod vs @staticmethod in Python


1
投票

def func(value, *args, **kwargs): pass func() # <--- TypeError: func() missing 1 required positional argument: 'value' func(a=1, b=2) # <--- TypeError: func() missing 1 required positional argument: 'value' # passing the required arg solves the issue func(30) # <--- OK func(3, a=1, b=2) # <--- OK

上面的例子非常简单,但是如果
func()

是从模块导入的,那就不太明显了。例如,numpy 模块的

allclose
函数(检查两个数组是否足够接近)需要两个位置参数。如果您将两个数组作为元组/列表传递,您将在标题中得到 TypeError。
import numpy as np
np.allclose(([1, 2], [1, 1]))  # <--- TypeError
np.allclose([1, 2], [1, 1])    # <--- OK



0
投票
之前

class Person: def __init__(self, full_name, uuid, user_type, working_hours=None): self.full_name = full_name self.uuid = uuid def load_data(filename): print("Data") def load_readers(self): return self.load_data("readers.txt")

之后

class Person: def __init__(self, full_name, uuid, user_type): self.full_name = full_name self.uuid = uuid self.user_type = user_type def load_data(self, filename): print("Data") def load_readers(self): return self.load_data("readers.txt")

在我的情况下,错误是由于 
load_data()

函数中缺少 self 关键字引起的,该关键字在

load_readers()
函数中使用。
尝试检查您的所有函数是否都有 

self

关键字

我如何称呼班级

if __name__ == '__main__': person = Person("Foo", 1222, "READER") print(person.load_readers())

所以不要使用类名,而是先初始化类对象来调用函数。

© www.soinside.com 2019 - 2024. All rights reserved.