Python类方法调用疑问:类与实例传参及self机制解析
Python类实例与方法调用的概念解析
定义的基础类
class Duck: def quack(self): print("quack") class Dog: def bark(self): print("I just bark")
两种ItQuacks实现及调用现象
Case 1
class ItQuacks: def __init__(self, animal): animal.quack()
- 调用
ItQuacks(Duck):无输出(实际会触发参数缺失报错) - 调用
ItQuacks(Duck()):正常打印quack
Case 2
class ItQuacks: def __init__(self, animal): animal.quack(self)
- 调用
ItQuacks(Duck):正常打印quack
问题与解答
核心疑问:Duck()是否默认带有self?
先明确几个关键概念:
- 类与实例的区别
Duck是类本身,相当于一个“模板”;Duck()是通过类创建的实例对象,是模板生成的具体个体。
- self参数的作用
类中定义的def quack(self):这类方法属于实例方法,第一个参数self固定代表调用该方法的实例对象。当用实例调用方法时(比如duck = Duck(); duck.quack()),Python会自动把实例duck传递给self参数,不需要手动传入。
逐个现象解析
Case 1中
ItQuacks(Duck)无输出:
这里传入的animal是类Duck,不是实例。直接调用Duck.quack()时,实例方法quack需要接收self参数(代表Duck实例),但此时没有传入,会触发TypeError错误(你没看到输出大概率是没注意到报错)。而ItQuacks(Duck())传入的是Duck实例,调用quack()时Python自动把该实例传给self,所以正常执行打印。Case 2中
ItQuacks(Duck)能打印:
这里调用animal.quack(self),其中的self是ItQuacks类的实例(当前__init__方法所属的对象)。相当于把ItQuacks实例手动传给了Duck.quack的self参数,由于quack方法只是打印字符串,没有用到self的任何属性,所以代码能正常执行。但这是不符合规范的写法,因为quack方法设计上是给Duck实例使用的,传入其他类的实例违背了方法的设计意图。
结论
Duck()(实例对象)并不“带有self”——self是实例方法的参数,当用实例调用方法时,Python会自动将该实例作为self传入方法,不需要手动传递。
内容的提问来源于stack exchange,提问作者Venkatarao Dadi
相关产品推荐
相关产品推荐

