💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 5.8. 类属性介绍 你已经知道了[数据属性](userdict.html#fileinfo.userdict.init.example "例 5.9. 定义 UserDict 类"),它们是被一个特定的类实例所拥有的变量。Python 也支持类属性,它们是由类本身所拥有的。 ## 例 5.17. 类属性介绍 ``` class MP3FileInfo(FileInfo): "store ID3v1.0 MP3 tags" tagDataMap = {"title" : ( 3, 33, stripnulls), "artist" : ( 33, 63, stripnulls), "album" : ( 63, 93, stripnulls), "year" : ( 93, 97, stripnulls), "comment" : ( 97, 126, stripnulls), "genre" : (127, 128, ord)} ``` ``` >>> import fileinfo >>> fileinfo.MP3FileInfo <class fileinfo.MP3FileInfo at 01257FDC> >>> fileinfo.MP3FileInfo.tagDataMap {'title': (3, 33, <function stripnulls at 0260C8D4>), 'genre': (127, 128, <built-in function ord>), 'artist': (33, 63, <function stripnulls at 0260C8D4>), 'year': (93, 97, <function stripnulls at 0260C8D4>), 'comment': (97, 126, <function stripnulls at 0260C8D4>), 'album': (63, 93, <function stripnulls at 0260C8D4>)} >>> m = fileinfo.MP3FileInfo() >>> m.tagDataMap {'title': (3, 33, <function stripnulls at 0260C8D4>), 'genre': (127, 128, <built-in function ord>), 'artist': (33, 63, <function stripnulls at 0260C8D4>), 'year': (93, 97, <function stripnulls at 0260C8D4>), 'comment': (97, 126, <function stripnulls at 0260C8D4>), 'album': (63, 93, <function stripnulls at 0260C8D4>)} ``` | | | | --- | --- | | \[1\] | `MP3FileInfo` 是类本身,不是任何类的特别实例。 | | \[2\] | `tagDataMap` 是一个类属性:字面的意思,一个类的属性。它在创建任何类实例之前就有效了。 | | \[3\] | 类属性既可以通过直接对类的引用,也可以通过对类的任意实例的引用来使用。 | > 注意 > 在 Java 中,静态变量 (在 Python 中叫类属性) 和实例变量 (在 Python 中叫数据属性) 两者都是紧跟在类定义之后定义的 (一个有 `static` 关键字,一个没有)。在 Python 中,只有类属性可以定义在这里,数据属性定义在 `__init__` 方法中。 类属性可以作为类级别的常量来使用 (这就是为什么我们在 `MP3FileInfo` 中使用它们),但是它们不是真正的常量。你也可以修改它们。 > 注意 > 在 Python 中没有常量。如果你试图努力的话什么都可以改变。这一点满足 Python 的核心原则之一:坏的行为应该被克服而不是被取缔。如果你真正想改变 `None` 的值,也可以做到,但当无法调试的时候别来找我。 ## 例 5.18. 修改类属性 ``` >>> class counter: ... count = 0 ... def __init__(self): ... self.__class__.count += 1 ... >>> counter <class __main__.counter at 010EAECC> >>> counter.count 0 >>> c = counter() >>> c.count 1 >>> counter.count 1 >>> d = counter() >>> d.count 2 >>> c.count 2 >>> counter.count 2 ``` | | | | --- | --- | | \[1\] | `count` 是 `counter` 类的一个类属性。 | | \[2\] | `__class__` 是每个类实例的一个内置属性 (也是每个类的)。它是一个类的引用,而 `self` 是一个类 (在本例中,是 `counter` 类) 的实例。 | | \[3\] | 因为 `count` 是一个类属性,它可以在我们创建任何类实例之前,通过直接对类引用而得到。 | | \[4\] | 创建一个类实例会调用 `__init__` 方法,它会给类属性 `count` 加 `1`。这样会影响到类自身,不只是新创建的实例。 | | \[5\] | 创建第二个实例将再次增加类属性 `count`。注意类属性是如何被类和所有类实例所共享的。 |