Python中class的self参数取值及__init__方法工作原理疑问
问题描述
我正在学习Python的类与对象,遇到了如下代码:
class ComplexNumber: def __init__(self,r = 0,i = 0): self.real = r self.imag = i def getData(self): print("{0}+{1}j".format(self.real,self.imag)) # Create a new ComplexNumber object c1 = ComplexNumber(2,3) # Call getData() function # Output: 2+3j c1.getData()我知道调用
ComplexNumber时第一个参数是c1本身,会被赋值给self,随后在__init__中r被赋值给self.real。我有疑问:程序是如何得知self的类型为ComplexNumber的?如果我没理解错,self.real或self.imag应该只能赋值给complex类的变量,但打印self的类型却显示:<class '__main__.ComplexNumber'>。
解答
其实你混淆了两个完全独立的概念:Python内置的complex类型,和你自己定义的ComplexNumber类,这二者没有任何默认关联哦!
关于self的类型问题
当你执行c1 = ComplexNumber(2,3)时,Python会直接创建一个属于你自定义ComplexNumber类的实例对象,然后自动把这个刚创建的实例作为第一个参数传递给__init__方法,也就是self。所以self本质上就是这个实例的引用,它的类型自然就是<class '__main__.ComplexNumber'>——因为它就是你这个类“生产”出来的对象,从创建的那一刻起类型就确定了,根本不需要程序额外“得知”。
关于self.real/self.imag与内置complex的关系
Python确实有内置的complex类型(比如直接写3+4j就能得到一个内置复数对象),但你写的ComplexNumber是一个完全独立的自定义类,和内置complex没有继承关系(除非你显式声明class ComplexNumber(complex):)。
所以self.real和self.imag只是你给这个自定义实例添加的普通属性,你可以给它们赋值任何类型的数据(整数、字符串甚至其他对象都可以),根本不存在“只能赋值给complex类的变量”这种限制——这是把自定义类和内置类型搞混啦。
如果想让你的自定义类和内置complex关联,可以让它继承内置complex类,这样你的实例就同时属于ComplexNumber和complex类型了:
class ComplexNumber(complex): def getData(self): print(f"{self.real}+{self.imag}j") c1 = ComplexNumber(2,3) print(type(c1)) # 输出: <class '__main__.ComplexNumber'> print(isinstance(c1, complex)) # 输出: True
回到你的原始代码,你的ComplexNumber是完全自主定义的类,self就是这个类的实例,所以它的类型显示为__main__.ComplexNumber是完全正常的结果~
内容的提问来源于stack exchange,提问作者Adarsh TS

