前言
关于类属性和实例对象定义就不讲了,只是写代码时遇到一个不错的例子,分享一下关于使用类属性的心得。
一、先来点结论
1、实例属性属于各个实例所有,互不干扰;
2、类属性属于类所有,所有实例共享一个属性;
3、不要对实例属性和类属性使用相同的名字,否则将产生难以发现的错误。
二、示例
问题描述:
为了统计学生人数,可以给Student类增加一个类属性,每创建一个实例,该属性自动增加。具体题目见廖老师文章末尾。 廖老师文章点击跳转
1.正确代码:
class Student(object):
count = 0
def __init__(self, name):
self.name = name
Student.count += 1
#测试
bart = Student('Bart')
print('Student.count: %s' % Student.count)
print('bart.count: %s' % bart.count)
#Output: Student.count: 1
# bart.count: 1
lisa = Student('Lisa')
print('Student.count: %s' % Student.count)
print('lisa.count: %s' % lisa.count)
#Output: Student.count: 2
# bart.count: 2
2.错误代码
2.1.1第一种错误代码
class Student(object):
count = 0
def __init__(self, name):
self.name = name
count += 1 #错误错误错误!!!!!!!!!!
bart = Student('Bart')
print('Student.count: %s' % Student.count)
print('bart.count: %s' % bart.count)
#Output: Student.count: 1
# bart.count: 1
lisa = Student('Lisa')
print('Student.count: %s' % Student.count)
print('lisa.count: %s' % lisa.count)
#Output: Student.count: 2
# bart.count: 2
报错:UnboundLocalError: local variable ‘count’ referenced before assignment
2.1.2第一种错误代码原因分析
报错大概意思:在赋值前使用了局部变量。也就是说,解释器将__init_函数中的count变量当作了局部变量。
2.2.1第二种错误代码
class Student(object):
count = 0
def __init__(self, name):
self.name = name
self.count += 1 #这里是指向实例的count了,不再是Student这个类的属性了
bart = Student('Bart')
print('Student.count: %s' % Student.count)
print('bart.count: %s' % bart.count)
#Output: Student.count: 0
# bart.count: 1
lisa = Student('Lisa')
print('Student.count: %s' % Student.count)
print('lisa.count: %s' % lisa.count)
#Output: Student.count: 0
# bart.count: 1
这里不报错,但是运行结果却不是题目想要的,对应输出已注释
2.2.2第二种错误代码分析
__init_函数中写成了self.count。很明显,self.count是指向了实例中的count。
故每次实例化时都会对count进行重新赋值,故每次实例化一个对象后,该对象的count永远是1。又因为函数中是对实例对象的count修改,并未对Student类中count这一类属性进行修改,故无论如何Student.count永远为0
三、总结
那些知识点很好理解,主要就是需要细心,并且扣代码一定要细心!