1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
|
<!DOCTYPE html
PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>5.8. Introducing Class Attributes</title>
<link rel="stylesheet" href="../diveintopython.css" type="text/css">
<link rev="made" href="mailto:f8dy@diveintopython.org">
<meta name="generator" content="DocBook XSL Stylesheets V1.52.2">
<meta name="keywords" content="Python, Dive Into Python, tutorial, object-oriented, programming, documentation, book, free">
<meta name="description" content="Python from novice to pro">
<link rel="home" href="../toc/index.html" title="Dive Into Python">
<link rel="up" href="index.html" title="Chapter 5. Objects and Object-Orientation">
<link rel="previous" href="special_class_methods2.html" title="5.7. Advanced Special Class Methods">
<link rel="next" href="private_functions.html" title="5.9. Private Functions">
</head>
<body>
<table id="Header" width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
<tr>
<td id="breadcrumb" colspan="5" align="left" valign="top">You are here: <a href="../index.html">Home</a> > <a href="../toc/index.html">Dive Into Python</a> > <a href="index.html">Objects and Object-Orientation</a> > <span class="thispage">Introducing Class Attributes</span></td>
<td id="navigation" align="right" valign="top"> <a href="special_class_methods2.html" title="Prev: “Advanced Special Class Methods”"><<</a> <a href="private_functions.html" title="Next: “Private Functions”">>></a></td>
</tr>
<tr>
<td colspan="3" id="logocontainer">
<h1 id="logo"><a href="../index.html" accesskey="1">Dive Into Python</a></h1>
<p id="tagline">Python from novice to pro</p>
</td>
<td colspan="3" align="right">
<form id="search" method="GET" action="http://www.google.com/custom">
<p><label for="q" accesskey="4">Find: </label><input type="text" id="q" name="q" size="20" maxlength="255" value=" "> <input type="submit" value="Search"><input type="hidden" name="cof" value="LW:752;L:http://diveintopython.org/images/diveintopython.png;LH:42;AH:left;GL:0;AWFID:3ced2bb1f7f1b212;"><input type="hidden" name="domains" value="diveintopython.org"><input type="hidden" name="sitesearch" value="diveintopython.org"></p>
</form>
</td>
</tr>
</table>
<!--#include virtual="/inc/ads" -->
<div class="section" lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title"><a name="fileinfo.classattributes"></a>5.8. Introducing Class Attributes
</h2>
</div>
</div>
<div></div>
</div>
<div class="abstract">
<p>You already know about <a href="userdict.html#fileinfo.userdict.init.example" title="Example 5.9. Defining the UserDict Class">data attributes</a>, which are variables owned by a specific instance of a class. <span class="application">Python</span> also supports class attributes, which are variables owned by the class itself.
</p>
</div>
<div class="example"><a name="fileinfo.classattributes.intro"></a><h3 class="title">Example 5.17. Introducing Class Attributes</h3><pre class="programlisting"><span class='pykeyword'>
class</span> MP3FileInfo(FileInfo):
<span class='pystring'>"store ID3v1.0 MP3 tags"</span>
tagDataMap = {<span class='pystring'>"title"</span> : ( 3, 33, stripnulls),
<span class='pystring'>"artist"</span> : ( 33, 63, stripnulls),
<span class='pystring'>"album"</span> : ( 63, 93, stripnulls),
<span class='pystring'>"year"</span> : ( 93, 97, stripnulls),
<span class='pystring'>"comment"</span> : ( 97, 126, stripnulls),
<span class='pystring'>"genre"</span> : (127, 128, ord)}</pre><pre class="screen"><tt class="prompt">>>> </tt><span class="userinput"><span class='pykeyword'>import</span> fileinfo</span>
<tt class="prompt">>>> </tt><span class="userinput">fileinfo.MP3FileInfo</span> <a name="fileinfo.classattributes.1.1"></a><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12">
<span class="computeroutput"><class fileinfo.MP3FileInfo at 01257FDC></span>
<tt class="prompt">>>> </tt><span class="userinput">fileinfo.MP3FileInfo.tagDataMap</span> <a name="fileinfo.classattributes.1.2"></a><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12">
<span class="computeroutput">{'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>)}</span>
<tt class="prompt">>>> </tt><span class="userinput">m = fileinfo.MP3FileInfo()</span> <a name="fileinfo.classattributes.1.3"></a><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12">
<tt class="prompt">>>> </tt><span class="userinput">m.tagDataMap</span>
<span class="computeroutput">{'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>)}</span></pre><div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td width="12" valign="top" align="left"><a href="#fileinfo.classattributes.1.1"><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12"></a>
</td>
<td valign="top" align="left"><tt class="classname">MP3FileInfo</tt> is the class itself, not any particular instance of the class.
</td>
</tr>
<tr>
<td width="12" valign="top" align="left"><a href="#fileinfo.classattributes.1.2"><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12"></a>
</td>
<td valign="top" align="left"><tt class="varname">tagDataMap</tt> is a class attribute: literally, an attribute of the class. It is available before creating any instances of the class.
</td>
</tr>
<tr>
<td width="12" valign="top" align="left"><a href="#fileinfo.classattributes.1.3"><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12"></a>
</td>
<td valign="top" align="left">Class attributes are available both through direct reference to the class and through any instance of the class.</td>
</tr>
</table>
</div>
</div><a name="compare.classattr.java"></a><table class="note" border="0" summary="">
<tr>
<td rowspan="2" align="center" valign="top" width="1%"><img src="../images/note.png" alt="Note" title="" width="24" height="24"></td>
</tr>
<tr>
<td colspan="2" align="left" valign="top" width="99%">In <span class="application">Java</span>, both static variables (called class attributes in <span class="application">Python</span>) and instance variables (called data attributes in <span class="application">Python</span>) are defined immediately after the class definition (one with the <tt class="literal">static</tt> keyword, one without). In <span class="application">Python</span>, only class attributes can be defined here; data attributes are defined in the <tt class="function">__init__</tt> method.
</td>
</tr>
</table>
<p>Class attributes can be used as class-level constants (which is how you use them in <tt class="classname">MP3FileInfo</tt>), but they are not really constants. You can also change them.
</p><a name="d0e13711"></a><table class="note" border="0" summary="">
<tr>
<td rowspan="2" align="center" valign="top" width="1%"><img src="../images/note.png" alt="Note" title="" width="24" height="24"></td>
</tr>
<tr>
<td colspan="2" align="left" valign="top" width="99%">There are no constants in <span class="application">Python</span>. Everything can be changed if you try hard enough. This fits with one of the core principles of <span class="application">Python</span>: bad behavior should be discouraged but not banned. If you really want to change the value of <tt class="literal">None</tt>, you can do it, but don't come running to me when your code is impossible to debug.
</td>
</tr>
</table>
<div class="example"><a name="fileinfo.classattributes.writeable.example"></a><h3 class="title">Example 5.18. Modifying Class Attributes</h3><pre class="screen"><tt class="prompt">>>> </tt><span class="userinput"><span class='pykeyword'>class</span><span class='pyclass'> counter</span>:</span>
<tt class="prompt">... </tt><span class="userinput">count = 0</span> <a name="fileinfo.classattributes.2.1"></a><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12">
<tt class="prompt">... </tt><span class="userinput"><span class='pykeyword'>def</span><span class='pyclass'> __init__</span>(self):</span>
<tt class="prompt">... </tt><span class="userinput"> self.__class__.count += 1</span> <a name="fileinfo.classattributes.2.2"></a><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12">
<tt class="prompt">... </tt>
<tt class="prompt">>>> </tt><span class="userinput">counter</span>
<span class="computeroutput"><class __main__.counter at 010EAECC></span>
<tt class="prompt">>>> </tt><span class="userinput">counter.count</span> <a name="fileinfo.classattributes.2.3"></a><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12">
<span class="computeroutput">0</span>
<tt class="prompt">>>> </tt><span class="userinput">c = counter()</span>
<tt class="prompt">>>> </tt><span class="userinput">c.count</span> <a name="fileinfo.classattributes.2.4"></a><img src="../images/callouts/4.png" alt="4" border="0" width="12" height="12">
<span class="computeroutput">1</span>
<tt class="prompt">>>> </tt><span class="userinput">counter.count</span>
<span class="computeroutput">1</span>
<tt class="prompt">>>> </tt><span class="userinput">d = counter()</span> <a name="fileinfo.classattributes.2.5"></a><img src="../images/callouts/5.png" alt="5" border="0" width="12" height="12">
<tt class="prompt">>>> </tt><span class="userinput">d.count</span>
<span class="computeroutput">2</span>
<tt class="prompt">>>> </tt><span class="userinput">c.count</span>
<span class="computeroutput">2</span>
<tt class="prompt">>>> </tt><span class="userinput">counter.count</span>
<span class="computeroutput">2</span></pre><div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td width="12" valign="top" align="left"><a href="#fileinfo.classattributes.2.1"><img src="../images/callouts/1.png" alt="1" border="0" width="12" height="12"></a>
</td>
<td valign="top" align="left"><tt class="varname">count</tt> is a class attribute of the <tt class="classname">counter</tt> class.
</td>
</tr>
<tr>
<td width="12" valign="top" align="left"><a href="#fileinfo.classattributes.2.2"><img src="../images/callouts/2.png" alt="2" border="0" width="12" height="12"></a>
</td>
<td valign="top" align="left"><tt class="literal">__class__</tt> is a built-in attribute of every class instance (of every class). It is a reference to the class that <tt class="varname">self</tt> is an instance of (in this case, the <tt class="classname">counter</tt> class).
</td>
</tr>
<tr>
<td width="12" valign="top" align="left"><a href="#fileinfo.classattributes.2.3"><img src="../images/callouts/3.png" alt="3" border="0" width="12" height="12"></a>
</td>
<td valign="top" align="left">Because <tt class="varname">count</tt> is a class attribute, it is available through direct reference to the class, before you have created any instances of the
class.
</td>
</tr>
<tr>
<td width="12" valign="top" align="left"><a href="#fileinfo.classattributes.2.4"><img src="../images/callouts/4.png" alt="4" border="0" width="12" height="12"></a>
</td>
<td valign="top" align="left">Creating an instance of the class calls the <tt class="function">__init__</tt> method, which increments the class attribute <tt class="varname">count</tt> by <tt class="constant">1</tt>. This affects the class itself, not just the newly created instance.
</td>
</tr>
<tr>
<td width="12" valign="top" align="left"><a href="#fileinfo.classattributes.2.5"><img src="../images/callouts/5.png" alt="5" border="0" width="12" height="12"></a>
</td>
<td valign="top" align="left">Creating a second instance will increment the class attribute <tt class="varname">count</tt> again. Notice how the class attribute is shared by the class and all instances of the class.
</td>
</tr>
</table>
</div>
</div>
</div>
<table class="Footer" width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
<tr>
<td width="35%" align="left"><br><a class="NavigationArrow" href="special_class_methods2.html"><< Advanced Special Class Methods</a></td>
<td width="30%" align="center"><br> <span class="divider">|</span> <a href="index.html#fileinfo.divein" title="5.1. Diving In">1</a> <span class="divider">|</span> <a href="importing_modules.html" title="5.2. Importing Modules Using from module import">2</a> <span class="divider">|</span> <a href="defining_classes.html" title="5.3. Defining Classes">3</a> <span class="divider">|</span> <a href="instantiating_classes.html" title="5.4. Instantiating Classes">4</a> <span class="divider">|</span> <a href="userdict.html" title="5.5. Exploring UserDict: A Wrapper Class">5</a> <span class="divider">|</span> <a href="special_class_methods.html" title="5.6. Special Class Methods">6</a> <span class="divider">|</span> <a href="special_class_methods2.html" title="5.7. Advanced Special Class Methods">7</a> <span class="divider">|</span> <span class="thispage">8</span> <span class="divider">|</span> <a href="private_functions.html" title="5.9. Private Functions">9</a> <span class="divider">|</span> <a href="summary.html" title="5.10. Summary">10</a> <span class="divider">|</span>
</td>
<td width="35%" align="right"><br><a class="NavigationArrow" href="private_functions.html">Private Functions >></a></td>
</tr>
<tr>
<td colspan="3"><br></td>
</tr>
</table>
<div class="Footer">
<p class="copyright">Copyright © 2000, 2001, 2002, 2003, 2004 <a href="mailto:mark@diveintopython.org">Mark Pilgrim</a></p>
</div>
</body>
</html>
|