<< >>

diveintopython.org |

Python for experienced programmers

## 3.7. 类属性

你已经知道了数据属性，它们是被一个特定的类定例所拥有的变量。Python也支持类属性，它们是由类本身所拥有的。

例 3.14. 类属性介绍

    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>)}

| `MP3FileInfo` 是类本身，不是任何类的特别实例。
| `tagDataMap` 是一个类属性：字面的意思，一个类的属性。它是在创建任何类实例之前就有效了。
| 类属性既可以通过直接对类的引用，也可以通过对类的任意实例的引用来使用。

类属性可以作为类级别的常量来使用(这就是为什么我们在 `MP3FileInfo` 中使用它们)，但是它们不是真正的常量。[3] 你也可以修改它们。

例 3.15. 修改类属性

    >>> 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

| `count` 是 `counter` 类的一个类属性。
| `__class__` 是每个类实例的一个内置属性(也是每个类的)。它是一个类的引用，而 `self` 是一个类(在本例中， `是 counter` 类)的实例。
| 因为 `count` 是一个类属性，它可以在我们创建任何类实例之前，通过直接对类引用而得到。
| 因为创建一个类实例会调用 `__init__` 方法，它会给类属性 `count` 加 `1`。这样会影响到类自身，不只是新创建的实例。
| 创建第二个实例将再次增加类属性 `count`。注意类属性是如何被类和所有类实例所共享的。某些程序语言(明显的是Powerbuilder)因为这个原因将类属性叫做“共享变量”。

脚注 |

[3] 在Python中没有常量。甚至内置函数都可以赋予一个新值。有一次，当我正在使用Python IDE时，我碰巧定义了一个叫 `dir` 的变量来保存目录的路径，接着在后面让我感到奇怪，为什么我的 `help` 函数给了我奇怪的错误。原因就是我不止是定义了一个 `dir` 变量，也重新定义了内置的 `dir` 函数。

« 高级专用类方法 | 私有函数 »