Python类属性和实例属性

2024年03月28日 Python教程 Python51

Python类属性和实例属性

其实类本身也是一个对象,它也有自己的属性。类的属性一般表示类的相关内容,如类的版本和作者等信息。类的属性的定义是在类里面直接定义一个变量即可。

下面我们给类 Student 添加版本和作者信息。

>>> class Student: # 定义类Student
… version = "1.0" # 类的属性version
… author = "python.cn" # 类的属性author

>>> Student # 查看类Student
<class '__main__.Student'>
>>> Student.version # 查看类的属性
'1.0'
>>> Student.author # 查看类的属性
'python.cn'

可以看到,类的属性的访问方法是“类名。属性名”。这些属性也是可以修改的,如可以修改Student类的version属性。

>>> Student.version = "1.1" # 修改类Student的属性version
>>> Student.version # 查看修改后的类Student的属性version的值
'1.1'

那么我们能否定义类的函数呢?其实也可以的,如下面的代码中的 Student 类就有一个自己的类的函数 info()。

>>> class Student: # 定义类Student
… version = "1.0"
… author = "python.cn"
… def info(): # 定义了类的函数
… print("version %s, author: %s" % (Student.version,
Student.author))

>>> hasattr(Student, "info") # 是否存在info属性
True
>>> Student.info # 查看info属性
<function Student.info at 0x105cb09d8>
>>> Student.info() # 使用info属性
version 1.0, author: python.cn

实例属性

Python是面向对象的,即使是最简单的一个整数,它也是一个对象,因此也有自己的ID和属性。在本节中,对象特指我们用自定义的类创建的对象。

由于实例对象是基于类创建出来的,所以对象会继承类的属性。通过下面的例子可以看到对象自动继承了类的所有属性。

>>> class Student: # 定义类Student
… version = "1.0"
… author = "python.cn"
… def info():
… print("version %s, author: %s" % (Student.version, Student.
author))

>>> student_a = Student() # 创建对象student_a
>>> student_a.version # student_a的属性version
'1.0'
>>> student_a.author # student_a的属性author
'python.cn'

需要注意的是,这些从类继承得到的对象,并不是复制下来的,它们是指向类的属性的。可以通过查看id的方法来观察这一点。

>>> id(student_a.version) # 对象的某个从类继承的属性等于相应的类属性
48991624
>>> id(Student.version)
48991624
>>> student_a.version is Student.version # 它们是同一个对象
True

还可以通过修改类属性来观察实例继承的属性也发生了变化。

>>> student_a.version # 对象属性
'1.0'
>>> Student.version = "1.1" # 修改类属性
>>> student_a.version # 对象属性也发生了改变
'1.1'

但是修改对象的属性不会反映到类的属性上。如下面的例子中,修改了对象的属性 author,但是类 Student 的 author 属性是没有变化的。

>>> student_a.author = "inst_author" # 修改对象的author属性
>>> student_a.author # 对象的author属性发生了改变
'inst_author'
>>> Student.author # 类的author属性没有发生变化
'python.cn'

比较特殊的情况是列表数据类型,它们可以在不改变 id 的情况下,发生内容的改变。如调用了 append() 接口函数,该列表的 id 不会发生变化,但其内容发生了变化。下面演示了这种情况。

>>> list_1 = [] # 构造一个列表
>>> list_1 # 查看列表内容
[]
>>> id(list_1) # 查看其id
48545224
>>> list_1.append(2) # 添加一个元素
>>> id(list_1) # id没有变化
48545224
>>> list_1 # 但是内容发生了变化
[2]

对于这种类型的属性,如果 id 没有发生变化,修改对象从类继承来的属性会导致类属性的值的变化。如下面的代码所示。

>>> class Student: # 定义类Student
… years = []
… def __init__(self): # 构造函数
… print("__init__() is Running")
… def __del__(self): # 销毁函数
… print("__del__() is Running")
… def append(self, element): # 添加元素
… self.years.append(element)
… def change(self, list): # 修改对象
… self.years = list
… # 类定义结束
>>> student_a = Student() # 创建一个对象
__init__() is Running
>>> student_a.years
[]
>>> id(student_a.years) # 可以发现对象属性和类属性有相同的id
49089736
>>> id(Student.years)
49089736
>>> student_a.append(1) # 修改years属性的内容,但是没有改变id
>>> id(student_a.years)
49089736
>>> student_a.years # 对象属性的内容改变了
[1]
>>> Student.years # 类属性的内容也改变了
[1]

如果使用的是赋值等操作,则对象属性的 id 会发生改变,这样对象属性和类属性就没有关联了,和我们前面讲到的情况一致。下面是修改了对象的 id,也就是使用新的对象来表示该属性的情形。

>>> id(Student.years) # 开始时对象属性和类属性是一个对象
49089736
>>> id(student_a.years)
49089736
>>> student_a.change([1,2,3]) # 重新赋值后对象属性的id发生了变化
>>> id(Student.years) # 现在对象属性和类属性已经没有关联了
49089736
>>> id(student_a.years)
48699528

上一节 下一节

本文链接:http://so.lmcjl.com/news/555/

展开阅读全文