Python类方法调用时因self参数引发TypeError的问题排查
问题原因与解决方法
这个报错的核心原因很简单:你把实例方法当成了类直接调用的方法来使用了,咱们一步步拆解清楚:
1. 先搞懂self到底是什么
在Python的类中,定义实例方法时第一个参数self是约定俗成的(你也可以换成别的名字,但几乎没人这么做),它代表的是当前类的实例对象本身。当你通过实例对象调用这个方法时,Python会自动把这个实例作为第一个参数传递给self,根本不需要你手动传参。
但如果你直接用类名.方法名的方式调用,Python就不会自动帮你传入self了——这时候方法会把你传入的5当成第一个参数self,而它还需要第二个参数x,自然就会报missing 1 required positional argument: 'x'的错误。
2. 两种正确的解决方式
方式一:先实例化test类,再调用方法
这是最符合Python类设计规范的做法,因为Pprint原本就是实例方法:
class node(): def __init__(self, test): self.test = test class test(): def Pprint(self, x): rootnode = node(x) print(rootnode.test) # 先创建test类的实例 my_test = test() # 通过实例调用方法,Python自动把my_test传给self my_test.Pprint(5)
方式二:把方法改成静态/类方法(适合不需要访问实例属性的场景)
如果你确实想直接用test.Pprint(5)这种方式调用,可以把方法改成静态方法或者类方法:
- 静态方法:用
@staticmethod装饰器,不需要self或cls参数,适合不需要访问类或实例属性的场景:
class node(): def __init__(self, test): self.test = test class test(): @staticmethod def Pprint(x): rootnode = node(x) print(rootnode.test) # 直接用类名调用 test.Pprint(5)
- 类方法:用
@classmethod装饰器,第一个参数是cls(代表类本身),适合需要访问类属性的场景:
class node(): def __init__(self, test): self.test = test class test(): @classmethod def Pprint(cls, x): rootnode = node(x) print(rootnode.test) test.Pprint(5)
3. 为什么删除self后能运行?
当你删除self参数后,这个方法就不再是实例方法了——它变成了一个定义在类里面的普通函数。这时候用test.Pprint(5)调用,就和调用普通函数一样,传入的5会被当作x参数,所以能正常运行。但这种写法不符合Python的类设计规范,不推荐这么做,还是用上面两种正确的方式更稳妥。
内容的提问来源于stack exchange,提问作者Emran Tamimi
相关产品推荐
相关产品推荐

