mirror of
https://github.com/kennethreitz/dive-into-python3.git
synced 2026-06-05 23:10:17 +00:00
further porting
This commit is contained in:
@@ -1,115 +1,3 @@
|
||||
<h2 id="odbchelper.objects">2.4. Everything Is an Object</h2>
|
||||
<h2 id="odbchelper.testing">2.6. Testing Modules</h2>
|
||||
<p>Python modules are objects and have several useful attributes. You can use this to easily test your modules as you write them.
|
||||
Here's an example that uses the <code>if</code> <code>__name__</code> trick.
|
||||
<pre id="odbchelper.ifnametrick" class=programlisting>
|
||||
if __name__ == "__main__":</pre><p>Some quick observations before you get to the good stuff. First, parentheses are not required around the <code>if</code> expression. Second, the <code>if</code> statement ends with a colon, and is followed by <a href="#odbchelper.indenting" title="2.5. Indenting Code">indented code</a>.
|
||||
<table id="compare.equals.c" class=note border="0" summary="">
|
||||
|
||||
<td rowspan="2" align="center" valign="top" width="1%"><img src="images/note.png" alt="Note" title="" width="24" height="24"><td colspan="2" align="left" valign="top" width="99%">Like <abbr>C</abbr>, Python uses <code>==</code> for comparison and <code>=</code> for assignment. Unlike <abbr>C</abbr>, Python does not support in-line assignment, so there's no chance of accidentally assigning the value you thought you were comparing.
|
||||
<p>So why is this particular <code>if</code> statement a trick? Modules are objects, and all modules have a built-in attribute <code>__name__</code>. A module's <code>__name__</code> depends on how you're using the module. If you <code>import</code> the module, then <code>__name__</code> is the module's filename, without a directory path or file extension. But you can also run the module directly as a standalone
|
||||
program, in which case <code>__name__</code> will be a special default value, <code>__main__</code>.
|
||||
<pre class=screen><samp class=p>>>> </samp><kbd>import odbchelper</kbd>
|
||||
<samp class=p>>>> </samp>odbchelper.<code>__name__</code>
|
||||
'odbchelper'</pre><p>Knowing this, you can design a test suite for your module within the module itself by putting it in this <code>if</code> statement. When you run the module directly, <code>__name__</code> is <code>__main__</code>, so the test suite executes. When you import the module, <code>__name__</code> is something else, so the test suite is ignored. This makes it easier to develop and debug new modules before integrating
|
||||
them into a larger program.
|
||||
<table id="tip.mac.runasmain" class=tip border="0" summary="">
|
||||
|
||||
<td rowspan="2" align="center" valign="top" width="1%"><img src="images/tip.png" alt="Tip" title="" width="24" height="24"><td colspan="2" align="left" valign="top" width="99%">On MacPython, there is an additional step to make the <code>if</code> <code>__name__</code> trick work. Pop up the module's options menu by clicking the black triangle in the upper-right corner of the window, and
|
||||
make sure Run as __main__ is checked.
|
||||
<div class=itemizedlist>
|
||||
<h3>Further Reading on Importing Modules</h3>
|
||||
<ul>
|
||||
<li><a href="http://www.python.org/doc/current/ref/"><i class=citetitle>Python Reference Manual</i></a> discusses the low-level details of <a href="http://www.python.org/doc/current/ref/import.html">importing modules</a>.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h2 id="odbchelper.vardef">3.4. Declaring variables</h2>
|
||||
<p>Now that you know something about dictionaries, tuples, and lists (oh my!), let's get back to the sample program from <a href="#odbchelper">Chapter 2</a>, <code>odbchelper.py</code>.
|
||||
<p>Python has local and global variables like most other languages, but it has no explicit variable declarations. Variables spring
|
||||
into existence by being assigned a value, and they are automatically destroyed when they go out of scope.
|
||||
<div class=example><h3 id="myparamsdef">Example 3.17. Defining the <var>myParams</var> Variable</h3><pre><code>
|
||||
if __name__ == "__main__":
|
||||
myParams = {"server":"mpilgrim", \
|
||||
"database":"master", \
|
||||
"uid":"sa", \
|
||||
"pwd":"secret" \
|
||||
}</pre><p>Notice the indentation. An <code>if</code> statement is a code block and needs to be indented just like a function.
|
||||
<p>Also notice that the variable assignment is one command split over several lines, with a backslash (“<code>\</code>”) serving as a line-continuation marker.
|
||||
<table id="tip.multiline" class=note border="0" summary="">
|
||||
|
||||
<td rowspan="2" align="center" valign="top" width="1%"><img src="images/note.png" alt="Note" title="" width="24" height="24"><td colspan="2" align="left" valign="top" width="99%">When a command is split among several lines with the line-continuation marker (“<code>\</code>”), the continued lines can be indented in any manner; Python's normally stringent indentation rules do not apply. If your Python <abbr>IDE</abbr> auto-indents the continued line, you should probably accept its default unless you have a burning reason not to.
|
||||
<p><a name="tip.implicitmultiline"></a>Strictly speaking, expressions in parentheses, straight brackets, or curly braces (like <a href="#myparamsdef" title="Example 3.17. Defining the myParams Variable">defining a dictionary</a>) can be split into multiple lines with or without the line continuation character (“<code>\</code>”). I like to include the backslash even when it's not required because I think it makes the code easier to read, but that's
|
||||
a matter of style.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[unbound variable exception example was here]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3 id="odbchelper.multiassign">3.4.2. Assigning Multiple Values at Once</h3>
|
||||
<p>One of the cooler programming shortcuts in Python is using sequences to assign multiple values at once.
|
||||
<div class=example><h3>Example 3.19. Assigning multiple values at once</h3><pre class=screen><samp class=p>>>> </samp><kbd>v = ('a', 'b', 'e')</kbd>
|
||||
<samp class=p>>>> </samp><kbd>(x, y, z) = v</kbd> <span>①</span>
|
||||
<samp class=p>>>> </samp><kbd>x</kbd>
|
||||
'a'
|
||||
<samp class=p>>>> </samp><kbd>y</kbd>
|
||||
'b'
|
||||
<samp class=p>>>> </samp><kbd>z</kbd>
|
||||
'e'</pre>
|
||||
<ol>
|
||||
<li><var>v</var> is a tuple of three elements, and <code>(x, y, z)</code> is a tuple of three variables. Assigning one to the other assigns each of the values of <var>v</var> to each of the variables, in order.
|
||||
<p>This has all sorts of uses. I often want to assign names to a range of values. In <abbr>C</abbr>, you would use <code>enum</code> and manually list each constant and its associated value, which seems especially tedious when the values are consecutive.
|
||||
In Python, you can use the built-in <code>range</code> function with multi-variable assignment to quickly assign consecutive values.
|
||||
<div class=example><h3 id="odbchelper.multiassign.range">Example 3.20. Assigning Consecutive Values</h3><pre class=screen><samp class=p>>>> </samp><kbd>range(7)</kbd> <span>①</span>
|
||||
[0, 1, 2, 3, 4, 5, 6]
|
||||
<samp class=p>>>> </samp><kbd>(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7)</kbd> <span>②</span>
|
||||
<samp class=p>>>> </samp><kbd>MONDAY</kbd> <span>③</span>
|
||||
0
|
||||
<samp class=p>>>> </samp><kbd>TUESDAY</kbd>
|
||||
1
|
||||
<samp class=p>>>> </samp><kbd>SUNDAY</kbd>
|
||||
6</pre>
|
||||
<ol>
|
||||
<li>The built-in <code>range</code> function returns a list of integers. In its simplest form, it takes an upper limit and returns a zero-based list counting
|
||||
up to but not including the upper limit. (If you like, you can pass other parameters to specify a base other than <code>0</code> and a step other than <code>1</code>. You can <code>print range.__doc__</code> for details.)
|
||||
<li><var>MONDAY</var>, <var>TUESDAY</var>, <var>WEDNESDAY</var>, <var>THURSDAY</var>, <var>FRIDAY</var>, <var>SATURDAY</var>, and <var>SUNDAY</var> are the variables you're defining. (This example came from the <code>calendar</code> module, a fun little module that prints calendars, like the <abbr>UNIX</abbr> program <code>cal</code>. The <code>calendar</code> module defines integer constants for days of the week.)
|
||||
<li>Now each variable has its value: <var>MONDAY</var> is <code>0</code>, <var>TUESDAY</var> is <code>1</code>, and so forth.
|
||||
<p>You can also use multi-variable assignment to build functions that return multiple values, simply by returning a tuple of
|
||||
all the values. The caller can treat it as a tuple, or assign the values to individual variables. Many standard Python libraries do this, including the <code>os</code> module, which you'll discuss in <a href="#filehandling">Chapter 6</a>.
|
||||
<div class=itemizedlist>
|
||||
<h3>Further Reading on Variables</h3>
|
||||
<ul>
|
||||
<li><a href="http://www.python.org/doc/current/ref/"><i class=citetitle>Python Reference Manual</i></a> shows examples of <a href="http://www.python.org/doc/current/ref/implicit-joining.html">when you can skip the line continuation character</a> and <a href="http://www.python.org/doc/current/ref/explicit-joining.html">when you need to use it</a>.
|
||||
|
||||
<li><a href="http://www.ibiblio.org/obp/thinkCSpy/" title="Python book for computer science majors"><i class=citetitle>How to Think Like a Computer Scientist</i></a> shows how to use multi-variable assignment to <a href="http://www.ibiblio.org/obp/thinkCSpy/chap09.htm">swap the values of two variables</a>.
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class=example><h3>Example 6.12. Introducing <code><code>sys</code>.modules</code></h3><pre class=screen><samp class=p>>>> </samp><kbd>import sys</kbd> <span>①</span>
|
||||
<samp class=p>>>> </samp><kbd>print '\n'.join(sys.modules.keys())</kbd> <span>②</span>
|
||||
<samp>win32api
|
||||
|
||||
Reference in New Issue
Block a user