实例属性和类属性
1. 实例属性
- Python 是动态语言,根据类创建的实例可以任意绑定属性。
- 给实例绑定属性的两种方式:
- 通过实例变量:
s.score = 90 - 通过
self:在__init__中self.name = name
- 通过实例变量:
class Student(object):
def __init__(self, name):
self.name = name
s = Student('Bob')
s.score = 90 # 实例变量绑定
2. 类属性
- 若类本身需要绑定属性,可直接在 class 中定义(与
def同级),这种属性是类属性,归类所有。 - 类的所有实例都可以访问类属性;实例没有该属性时,会向上查找类的属性。
class Student(object):
name = 'Student' # 类属性
s = Student()
print(s.name) # 'Student',实例没有 name,找到类的 name
print(Student.name) # 'Student'
3. 实例属性与类属性同名时(优先级)
- 实例属性优先级高于类属性:若实例绑定了同名属性,会屏蔽类属性;通过实例访问到的是实例属性,通过类名访问到的仍是类属性。
- 删除实例的同名属性后,再通过实例访问会再次找到类属性。
s.name = 'Michael' # 给实例绑定 name
print(s.name) # 'Michael',屏蔽类属性
print(Student.name) # 'Student',类属性仍在
del s.name # 删除实例的 name
print(s.name) # 'Student',又找到类属性
4. 注意:不要同名
- 不要对实例属性和类属性使用相同名字。同名实例属性会屏蔽类属性,删除实例属性后又访问到类属性,容易混淆、难以排查错误。
5. 练习:用类属性统计实例数
- 给类增加类属性(如
count = 0),在__init__里用类名修改:Student.count += 1,每创建一个实例自动加 1。
class Student(object):
count = 0
def __init__(self, name):
self.name = name
Student.count += 1 # 类属性,用类名访问
# Student.count 随实例创建递增
小结
| 类型 | 归属 | 定义位置 | 访问 |
|---|---|---|---|
| 实例属性 | 各个实例,互不干扰 | self.xxx 或 实例.xxx | 实例.xxx |
| 类属性 | 类,所有实例共享 | class 内与 def 同级,如 name = 'Student' | 类名.xxx 或 实例.xxx(无同名实例属性时) |
- 优先级:同名时实例属性覆盖类属性;删除实例属性后,再访问会得到类属性。
- 建议:实例属性和类属性不要用相同名字。
记忆:实例属性归实例、类属性归类且共享;同名实例会挡住类属性;统计用类属性 + 类名修改。