跳到主要内容

实例属性和类属性

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(无同名实例属性时)
  • 优先级:同名时实例属性覆盖类属性;删除实例属性后,再访问会得到类属性。
  • 建议实例属性和类属性不要用相同名字

记忆:实例属性归实例、类属性归类且共享;同名实例会挡住类属性;统计用类属性 + 类名修改。