Python类方法内属性赋值后调用报错原因咨询
你的Python类属性问题拆解
嘿,我来帮你捋清楚这段代码里的问题所在~先看看你的代码:
class Person(object): def __init__(self, age, height): self.age = age self.height = height def weight_kg(self): self.weight = 60 def ratio_kg2height(self): self.ratio = self.weight / self.height return self.ratio mike = Person(23, 170) print mike.weight print mike.ratio_kg2height() print mike.ratio
为什么三个print都会报错?
其实核心原因很简单:你定义的这些属性(weight、ratio)只有在对应的方法被调用后,才会被添加到实例上,而你现在根本没调用这些方法!
- 第一个
print mike.weight报错:weight是在weight_kg()方法里给实例绑定的属性,但你创建mike后从来没调用过mike.weight_kg(),所以mike实例压根没有weight这个属性。 - 第二个
print mike.ratio_kg2height()报错:这个方法里要用到self.weight,但同样因为weight_kg()没被调用,self.weight不存在,所以会先抛出AttributeError,连计算比值的步骤都到不了。 - 第三个
print mike.ratio报错:就算前面的问题解决了,ratio也是在ratio_kg2height()方法里才被定义的,必须先调用这个方法,mike才会有ratio属性。
为什么别人在__init__外赋值属性能正常调用?
你看到的那些代码,要么是在使用属性前已经调用了定义属性的方法,要么是在依赖的方法内部确保了属性已经被初始化。比如如果方法B依赖方法A里定义的属性,通常会在方法B里先调用方法A,或者在__init__里提前调用方法A,保证实例创建时就有这个属性。
修正方案
这里给你两种常见的解决思路:
思路1:在初始化时就调用方法绑定属性
如果weight是每个实例都需要的固定值,直接在__init__里调用weight_kg(),这样实例一创建就有weight属性:
class Person(object): def __init__(self, age, height): self.age = age self.height = height self.weight_kg() # 初始化时自动调用,绑定weight属性 def weight_kg(self): self.weight = 60 def ratio_kg2height(self): self.ratio = self.weight / self.height return self.ratio mike = Person(23, 170) print(mike.weight) # 输出60 print(mike.ratio_kg2height()) # 输出60/170的结果≈0.3529 print(mike.ratio) # 输出同样的比值
思路2:在依赖方法里检查并初始化属性
如果weight是动态计算的(比如后续可能修改),可以在ratio_kg2height()里先检查weight是否存在,不存在就调用方法初始化:
class Person(object): def __init__(self, age, height): self.age = age self.height = height def weight_kg(self): self.weight = 60 # 这里可以改成动态计算逻辑 def ratio_kg2height(self): # 检查实例是否有weight属性,没有就调用方法初始化 if not hasattr(self, 'weight'): self.weight_kg() self.ratio = self.weight / self.height return self.ratio mike = Person(23, 170) print(mike.ratio_kg2height()) # 自动初始化weight后计算比值 print(mike.weight) # 现在能拿到60了 print(mike.ratio) # 拿到计算后的比值
另外补充一句:如果weight就是固定的60,其实没必要单独写weight_kg()方法,直接在__init__里写self.weight = 60会更简洁哦~
内容的提问来源于stack exchange,提问作者an offer can't refuse
相关产品推荐
相关产品推荐

