Source

JythonBook / html / chapter7.html

Full commit
  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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <title>Chapter 7: Modules and Packages &mdash; Jython Book v0.1 documentation</title>
    <link rel="stylesheet" href="_static/default.css" type="text/css" />
    <link rel="stylesheet" href="_static/pygments.css" type="text/css" />
    <script type="text/javascript">
      var DOCUMENTATION_OPTIONS = {
        URL_ROOT:    '',
        VERSION:     '0.1',
        COLLAPSE_MODINDEX: false,
        FILE_SUFFIX: '.html',
        HAS_SOURCE:  true
      };
    </script>
    <script type="text/javascript" src="_static/jquery.js"></script>
    <script type="text/javascript" src="_static/doctools.js"></script>
    <link rel="top" title="Jython Book v0.1 documentation" href="index.html" />
    <link rel="next" title="Chapter 8: Scripting with Jython" href="chapter8.html" />
    <link rel="prev" title="Chapter 6: Object Oriented Jython" href="chapter6.html" /> 
  </head>
  <body>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             accesskey="I">index</a></li>
        <li class="right" >
          <a href="chapter8.html" title="Chapter 8: Scripting with Jython"
             accesskey="N">next</a> |</li>
        <li class="right" >
          <a href="chapter6.html" title="Chapter 6: Object Oriented Jython"
             accesskey="P">previous</a> |</li>
        <li><a href="index.html">Jython Book v0.1 documentation</a> &raquo;</li> 
      </ul>
    </div>  

    <div class="document">
      <div class="documentwrapper">
        <div class="bodywrapper">
          <div class="body">
            
  <div class="section" id="chapter-7-modules-and-packages">
<h1>Chapter 7: Modules and Packages<a class="headerlink" href="#chapter-7-modules-and-packages" title="Permalink to this headline"></a></h1>
<p>Up until this chapter we have been looking at code at the level of the interactive console and
simple scripts. This works well for small examples, but when your program gets larger, it becomes
necessary to break programs up into smaller units.  In Python, the basic building block for these
units in larger programs is the module.</p>
<div class="section" id="imports-for-re-use">
<h2>Imports For Re-Use<a class="headerlink" href="#imports-for-re-use" title="Permalink to this headline"></a></h2>
<p>Breaking code up into modules helps to organize large code bases. Modules can be used to logically
separate code that belongs together, making programs easier to understand. Modules are helpful
for creating libraries that can be imported and used in different applications that share some
functionality. Jython&#8217;s standard library comes with a large number of modules that can be used
in your programs right away.</p>
<div class="section" id="definitions">
<h3>Definitions<a class="headerlink" href="#definitions" title="Permalink to this headline"></a></h3>
<p>Here are some basic concepts that are needed to discuss imports in Jython.</p>
<dl class="docutils">
<dt>Namespace</dt>
<dd>a logical grouping of unique identifiers.</dd>
<dt>Python Module</dt>
<dd>A file containing Python definitions and statements which in turn define a namespace. The module
name is the same as the file name with the suffix .py removed, so for example the Python file
“foo.py” defines the module “foo”.</dd>
<dt>Python Package</dt>
<dd>A directory containing an __init__.py file and usually some Python modules which are said
to be contained in the package. The __init__.py file is executed before any contained modules
are imported.</dd>
<dt>Java Package</dt>
<dd>Java packages organize Java classes into a namespace using nested directories. Java packages
do not require an __init__.py file. Also unlike Python packages, Java packages are explicitly
referenced in each Java file with a package directive at the top.</dd>
</dl>
</div>
<div class="section" id="the-import-statement">
<h3>The Import Statement<a class="headerlink" href="#the-import-statement" title="Permalink to this headline"></a></h3>
<p>In Java, the import statement is strictly a compiler directive that must occur at the top of the source
file. In Jython, the import statement is an expression that can occur anywhere in the source
file, and can even be conditionally executed.</p>
<p>As an example, a common idiom is to attempt to import something that may not be there in a try block,
and in the except block import a module that is known to be there.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span>  <span class="kn">from</span> <span class="nn">blah</span> <span class="kn">import</span> <span class="n">foo</span>
<span class="gp">... </span><span class="k">except</span><span class="p">:</span>
<span class="gp">... </span>  <span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
<span class="gp">... </span>    <span class="k">return</span> <span class="s">&quot;hello from backup foo&quot;</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foo</span><span class="p">()</span>
<span class="go">&#39;hello from backup foo&#39;</span>
<span class="go">&gt;&gt;&gt;</span>
</pre></div>
</div>
<p>If a module named blah had existed, the definition of foo would have been taken from there. Since no
such module existed, foo was defined in the except block, and when we called foo, the &#8216;hello from backup foo&#8217; string was returned.</p>
</div>
<div class="section" id="an-example-program">
<h3>An Example Program<a class="headerlink" href="#an-example-program" title="Permalink to this headline"></a></h3>
<p>To have a reasonable discussion about modules and packages, it helps to have a motivating example that is complex
enough for discussion, but simple enough to describe in a short space. I have chosen to show an application that
takes command line input that will then be used to search through the files in a given directory for a given bit
of text and list the files that match the input in a swing window.</p>
<div class="highlight-python"><pre>chapter7/
        searchdir.py
        search/
                __init__.py
                walker.py
                scanner.py</pre>
</div>
<p>The example contains one package: search, which is a package because it is a directory containing the special
__init__.py file.  In this case __init__.py is empty and so only serves as a marker that search is a package
. If __init__.py contained code, it would be executed before any of its containing modules could be imported.
Note that the directory chapter7 itself is not a package because it does not contain an __init__.py. There are
three modules in the example program: searchdir, search.input and search.scanner. The code for this program can be downloaded at XXX.</p>
<p>searchdir.py
~~~~~~~~~~~~</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">search.scanner</span> <span class="kn">as</span> <span class="nn">scanner</span>
<span class="kn">import</span> <span class="nn">sys</span>

<span class="n">help</span> <span class="o">=</span> <span class="s">&quot;&quot;&quot;</span>
<span class="s">Usage: search.py directory terms...</span>
<span class="s">&quot;&quot;&quot;</span>

<span class="n">args</span> <span class="o">=</span> <span class="n">sys</span><span class="o">.</span><span class="n">argv</span>

<span class="k">if</span> <span class="n">args</span> <span class="o">==</span> <span class="bp">None</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">args</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mf">2</span><span class="p">:</span>
    <span class="k">print</span> <span class="n">help</span>
    <span class="nb">exit</span><span class="p">()</span>

<span class="nb">dir</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mf">1</span><span class="p">]</span>
<span class="n">terms</span> <span class="o">=</span> <span class="n">args</span><span class="p">[</span><span class="mf">2</span><span class="p">:]</span>
<span class="n">scan</span> <span class="o">=</span> <span class="n">scanner</span><span class="o">.</span><span class="n">scan</span><span class="p">(</span><span class="nb">dir</span><span class="p">,</span> <span class="n">terms</span><span class="p">)</span>
<span class="n">scan</span><span class="o">.</span><span class="n">display</span><span class="p">()</span>
</pre></div>
</div>
<p>scanner.py
&#8212;&#8212;&#8212;-:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">search.walker</span> <span class="kn">import</span> <span class="n">DirectoryWalker</span>
<span class="kn">from</span> <span class="nn">javax.swing</span> <span class="kn">import</span> <span class="n">JFrame</span><span class="p">,</span> <span class="n">JTable</span><span class="p">,</span> <span class="n">WindowConstants</span>

<span class="k">class</span> <span class="nc">ScanResults</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">results</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">file</span><span class="p">,</span> <span class="n">line</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="nb">file</span><span class="p">,</span> <span class="n">line</span><span class="p">))</span>

    <span class="k">def</span> <span class="nf">display</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="n">colnames</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;file&#39;</span><span class="p">,</span> <span class="s">&#39;line&#39;</span><span class="p">]</span>
        <span class="n">table</span> <span class="o">=</span> <span class="n">JTable</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="p">,</span> <span class="n">colnames</span><span class="p">)</span>
        <span class="n">frame</span> <span class="o">=</span> <span class="n">JFrame</span><span class="p">(</span><span class="s">&quot;</span><span class="si">%i</span><span class="s"> Results&quot;</span> <span class="o">%</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">results</span><span class="p">))</span>
        <span class="n">frame</span><span class="o">.</span><span class="n">getContentPane</span><span class="p">()</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">table</span><span class="p">)</span>
        <span class="n">frame</span><span class="o">.</span><span class="n">size</span> <span class="o">=</span> <span class="mf">400</span><span class="p">,</span> <span class="mf">300</span>
        <span class="n">frame</span><span class="o">.</span><span class="n">defaultCloseOperation</span> <span class="o">=</span> <span class="n">WindowConstants</span><span class="o">.</span><span class="n">EXIT_ON_CLOSE</span>
        <span class="n">frame</span><span class="o">.</span><span class="n">visible</span> <span class="o">=</span> <span class="bp">True</span>

    <span class="k">def</span> <span class="nf">scan</span><span class="p">(</span><span class="nb">dir</span><span class="p">,</span> <span class="n">terms</span><span class="p">):</span>
        <span class="n">results</span> <span class="o">=</span> <span class="n">ScanResults</span><span class="p">()</span>
        <span class="k">for</span> <span class="n">filename</span> <span class="ow">in</span> <span class="n">DirectoryWalker</span><span class="p">(</span><span class="nb">dir</span><span class="p">):</span>
            <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">open</span><span class="p">(</span><span class="n">filename</span><span class="p">):</span>
                <span class="k">for</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">terms</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">term</span> <span class="ow">in</span> <span class="n">line</span><span class="p">:</span>
                        <span class="n">results</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">filename</span><span class="p">,</span><span class="n">line</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">results</span>
</pre></div>
</div>
<p>walker.py
&#8212;&#8212;&#8212;:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">os</span>

<span class="k">class</span> <span class="nc">DirectoryWalker</span><span class="p">:</span>
    <span class="c"># A forward iterator that traverses a directory tree. Adapted from an</span>
    <span class="c"># example in the eff-bot library guide: os-path-walk-example-3.py</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">directory</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">stack</span> <span class="o">=</span> <span class="p">[</span><span class="n">directory</span><span class="p">]</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">files</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">index</span> <span class="o">=</span> <span class="mf">0</span>

    <span class="k">def</span> <span class="nf">__getitem__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">index</span><span class="p">):</span>
        <span class="k">while</span> <span class="mf">1</span><span class="p">:</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="nb">file</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">files</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">index</span><span class="p">]</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">index</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">index</span> <span class="o">+</span> <span class="mf">1</span>
            <span class="k">except</span> <span class="ne">IndexError</span><span class="p">:</span>
                <span class="c"># pop next directory from stack</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">directory</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">files</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">listdir</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">directory</span><span class="p">)</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">index</span> <span class="o">=</span> <span class="mf">0</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="c"># got a filename</span>
                <span class="n">fullname</span> <span class="o">=</span> <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">directory</span><span class="p">,</span> <span class="nb">file</span><span class="p">)</span>
                <span class="k">if</span> <span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">isdir</span><span class="p">(</span><span class="n">fullname</span><span class="p">)</span> <span class="ow">and</span> <span class="ow">not</span>
                    <span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">islink</span><span class="p">(</span><span class="n">fullname</span><span class="p">)):</span>
                        <span class="bp">self</span><span class="o">.</span><span class="n">stack</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">fullname</span><span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="k">return</span> <span class="n">fullname</span>
</pre></div>
</div>
<p>If you run searchdir.py on it&#8217;s own directory like this:</p>
<p>Trying out the Example Code
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;:</p>
<div class="highlight-python"><pre>$ jython scanner.py . terms</pre>
</div>
<p>You  will get a swing table titled “5 Results” (possibly more if .class files are matched).  Let&#8217;s examine the import
statements used in this program.  The module searchdir contains two import statements::</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">search.scanner</span> <span class="kn">as</span> <span class="nn">scanner</span>
<span class="kn">import</span> <span class="nn">sys</span>
</pre></div>
</div>
<p>The first imports the module “search.scannar” and renames the module “scannar”.  The second imports the builtin
module “sys” and leaves the name as “sys”. The module “search.scannar” has two import statements:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">search.walker</span> <span class="kn">import</span> <span class="n">DirectoryWalker</span>
<span class="kn">from</span> <span class="nn">javax.swing</span> <span class="kn">import</span> <span class="n">JFrame</span><span class="p">,</span> <span class="n">JTable</span><span class="p">,</span> <span class="n">WindowConstants</span>
</pre></div>
</div>
<p>The first imports DirectoryWalker from the “search.walker” module.  Note that we had to do this even though search.walker
is in the same package as search.scanner. The last import is interesting because it imports the java classes like
JFrame from the java package javax.swing. Jython makes this sort of import look the same as other imports.  This
simple example shows how you can import code from different modules and packages to modularize your programs.</p>
</div>
</div>
<div class="section" id="types-of-import-statements">
<h2>Types of import statements<a class="headerlink" href="#types-of-import-statements" title="Permalink to this headline"></a></h2>
<p>The import statement comes in a variety of forms that allow much finer control over how importing brings named values into your current module.</p>
<p>Basic import Statements
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">module</span>
<span class="kn">from</span> <span class="nn">module</span> <span class="kn">import</span> <span class="n">submodule</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">submodule</span>
</pre></div>
</div>
<p>I will discuss each of the import statement forms in turn starting with:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">module</span>
</pre></div>
</div>
<p>This most basic type of import imports a module directly. Unlike Java, this form of import binds the leftmost module
name, so If you import a nested module like:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">javax.swing.JFrame</span>
</pre></div>
</div>
<p>You would need to refer to it as “javax.swing.JFrame” in your code.  In Java this would have imported “JFrame”.</p>
<p>from import Statements
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">module</span> <span class="kn">import</span> <span class="n">name</span>
</pre></div>
</div>
<p>This form of import allows you to import modules, classes or functions nested in other modules. This allows you
to achieve the result that a typical Java import gives. To get a JFrame in your Jython code you issue:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">javax.swing</span> <span class="kn">import</span> <span class="n">JFrame</span>
</pre></div>
</div>
<p>You can also use the from style of import to import all of the names in a module directly into your current
module using a <a href="#id1"><span class="problematic" id="id2">*</span></a>. This form of import is discouraged in the Python community, and is particularly troublesome
when importing from Java packages (in some cases it does not work, see chapter 10 for details) so you should avoid its use. It looks like this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">module</span> <span class="kn">import</span> <span class="o">*</span>
</pre></div>
</div>
<div class="section" id="relative-import-statements">
<h3>Relative import Statements<a class="headerlink" href="#relative-import-statements" title="Permalink to this headline"></a></h3>
<p>A new kind of import introduced in Python 2.5 is the explicit relative import. These import statements use dots to
indicate how far back you will walk from the current nesting of modules, with one dot meaning the current module.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">module</span>
<span class="kn">from</span> <span class="nn">..</span> <span class="kn">import</span> <span class="n">module</span>
<span class="kn">from</span> <span class="nn">.module</span> <span class="kn">import</span> <span class="n">submodule</span>
<span class="kn">from</span> <span class="nn">..module</span> <span class="kn">import</span> <span class="n">submodule</span>
</pre></div>
</div>
<p>Even though this style of importing has just been introduced, its use is discouraged. Explicit relative imports
are a reaction to the demand for implicit relative imports. If you look at the search.scanner package, you will see the import statement:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">search.walker</span> <span class="kn">import</span> <span class="n">DirectoryWalker</span>
</pre></div>
</div>
<p>Because search.walker sits in the same package as search.scanner, the import statement could have been:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">walker</span> <span class="kn">import</span> <span class="n">DirectoryWalker</span>
</pre></div>
</div>
<p>Some programmers like to use relative imports like this so that imports will survive module restructuring, but
these relative imports can be error prone because of the possibility of name clashes. The new syntax provides an
explicit way to use relative imports, though they too are still discouraged. The import statement above would look like this:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">.walker</span> <span class="kn">import</span> <span class="n">DirectoryWalker</span>
</pre></div>
</div>
</div>
<div class="section" id="aliasing-import-statements">
<h3>Aliasing import Statements<a class="headerlink" href="#aliasing-import-statements" title="Permalink to this headline"></a></h3>
<p>Any of the above imports can add an &#8220;as&#8221; clause to change import a module but give it a new name.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">module</span> <span class="kn">as</span> <span class="nn">alias</span>
<span class="kn">from</span> <span class="nn">module</span> <span class="kn">import</span> <span class="n">submodule</span> <span class="k">as</span> <span class="n">alias</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">submodule</span> <span class="k">as</span> <span class="n">alias</span>
</pre></div>
</div>
<p>This gives you enormous flexibility in your imports, so to go back to the Jframe example, you could issue:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">javax.swing.JFrame</span> <span class="kn">as</span> <span class="nn">Foo</span>
</pre></div>
</div>
<p>And instantiate a JFrame object with a call to Foo(), something that would surprise most Java developers coming to Jython.</p>
</div>
<div class="section" id="hiding-module-names">
<h3>Hiding Module Names<a class="headerlink" href="#hiding-module-names" title="Permalink to this headline"></a></h3>
<p>Typically when a module is imported, all of the names in the module are available to the importing
module. There are a couple of ways to hide these names from importing modules. Starting any name
with an underscore (_) which is the Python convention for marking names as private is the first way.
The second way to hide module names is to define a list named __all__, which should contain only
those names that you wish to have your module to expose.  As an example here is the value of __all__ at the top of Jython&#8217;s os module:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s">&quot;altsep&quot;</span><span class="p">,</span> <span class="s">&quot;curdir&quot;</span><span class="p">,</span> <span class="s">&quot;pardir&quot;</span><span class="p">,</span> <span class="s">&quot;sep&quot;</span><span class="p">,</span> <span class="s">&quot;pathsep&quot;</span><span class="p">,</span>
           <span class="s">&quot;linesep&quot;</span><span class="p">,</span> <span class="s">&quot;defpath&quot;</span><span class="p">,</span> <span class="s">&quot;name&quot;</span><span class="p">,</span> <span class="s">&quot;path&quot;</span><span class="p">,</span>
           <span class="s">&quot;SEEK_SET&quot;</span><span class="p">,</span> <span class="s">&quot;SEEK_CUR&quot;</span><span class="p">,</span> <span class="s">&quot;SEEK_END&quot;</span><span class="p">]</span>
</pre></div>
</div>
<p>Note that you can add to __all__ inside of a module to expand the exposed names of that module.
In fact, the os module in Jython does just this to conditionally expose names based on the operating
system that Jython is running on.</p>
</div>
</div>
<div class="section" id="module-search-path-compilation-and-loading">
<h2>Module Search Path, Compilation, and Loading<a class="headerlink" href="#module-search-path-compilation-and-loading" title="Permalink to this headline"></a></h2>
<div class="section" id="compilation">
<h3>Compilation<a class="headerlink" href="#compilation" title="Permalink to this headline"></a></h3>
<p>Despite the popular belief that Jython is an “interpreted, not compiled”, in reality all Jython code
is turned into Java bytecodes before execution.  These bytecodes are not always saved to disk, but when
you see Jython execute any code, even in an eval or an exec, you can be sure that bytecodes are getting
fed to the JVM. The sole exception to this that I know of is the experimental pycimport module that I
will describe in the section on sys.meta_path below, which interprets CPython bytecodes instead of producing Java bytecodes.</p>
</div>
<div class="section" id="module-search-path-and-loading">
<h3>Module search Path and Loading<a class="headerlink" href="#module-search-path-and-loading" title="Permalink to this headline"></a></h3>
<p>Understanding the process of module search and loading is more complicated in Jython than in either
CPython or Java because Jython can search both Java&#8217;s CLASSPATH and Python&#8217;s path. We&#8217;ll start by looking
at Python&#8217;s path and sys.path. When you issue an import, sys.path defines the path that Jython will use
to search for the name you are trying to import. The objects within the sys.path list tell Jython where
to search for modules. Most of these objects point to directories, but there are a few special items that
can be in sys.path for Jython that are not just pointers to directories. Trying to import a file that
does not reside anywhere in the sys.path (and also cannot be found in the CLASSPATH) raises an ImportError
exception. Let&#8217;s fire up a command line and look at sys.path.</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">path</span>
<span class="go">[&#39;&#39;, &#39;/Users/frank/jython/Lib&#39;, &#39;__classpath__&#39;, &#39;__pyclasspath__/&#39;,</span>
<span class="go">&#39;/Users/frank/jython/Lib/site-packages&#39;]</span>
</pre></div>
</div>
<p>The first blank entry (&#8216;&#8217;) tells Jython to look in the current directory for modules. The second entry
points to Jython&#8217;s Lib directory that contains the core Jython modules. The third and forth entries are
special markers that we will discuss later, and the last points to the site-packages directory where new
libraries can be installed when you issue setuptools directives from Jython (see Chapter XXX for more about setuptools).</p>
</div>
<div class="section" id="import-hooks">
<h3>Import Hooks<a class="headerlink" href="#import-hooks" title="Permalink to this headline"></a></h3>
<p>To understand the way that Jython imports Java classes we have to understand a bit about the Python import
protocol.  I won&#8217;t get into every detail, for that you would want to look at PEP 302 .</p>
<p>Briefly, we first try any custom importers registered on sys.meta_path. If one of them is capable of
importing the requested module, allow that importer to handle it. Next, we try each of the entries on
sys.path. For each of these, we find the first hook registered on sys.path_hooks that can handle the
path entry. If we find an import hook and it successfully imports the module, we stop. If this did not work,
we try the builtin import logic. If that also fails, an ImportError is thrown. So let&#8217;s look at Jython&#8217;s path_hooks.</p>
<p>sys.path_hooks
&#8212;&#8212;&#8212;&#8212;&#8211;</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">path_hooks</span>
<span class="go">[&lt;type &#39;org.python.core.JavaImporter&#39;&gt;, &lt;type &#39;zipimport.zipimporter&#39;&gt;,</span>
<span class="go">&lt;type &#39;ClasspathPyImporter&#39;&gt;]</span>
</pre></div>
</div>
<p>Each of these path_hooks entries specifies a path_hook that will attempt to import special fies. JavaImporter,
as it&#8217;s name implies, allows the dynamic loading of Java packages and classes that are specified at runtime.
For example, if you want to include a jar at runtime you can execute the following code, which will then get
picked up by the JavaImporter hook the next time that an import is attempted:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">sys</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">&quot;/Users/frank/lib/mysql-connector-java-5.1.6.jar&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">com.mysql</span>
<span class="go">*sys-package-mgr*: processing new jar, &#39;/Users/frank/lib/mysql-connector-java-5.1.6.jar&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">(</span><span class="n">com</span><span class="o">.</span><span class="n">mysql</span><span class="p">)</span>
<span class="go">[&#39;__name__&#39;, &#39;jdbc&#39;]</span>
</pre></div>
</div>
</div>
<div class="section" id="sys-meta-path">
<h3>sys.meta_path<a class="headerlink" href="#sys-meta-path" title="Permalink to this headline"></a></h3>
<p>Adding entries to sys.meta_path allows you to add import behaviors that will occur before any other import
is attempted, even the default builtin importing behavior.  This can be a very powerful tool, allowing you
to do all sorts of interesting things.  As an example, I will talk about an experimental module that ships
with Jython 2.5.  That module is pycimport.  If you start up jython and issue:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">pycimport</span>
</pre></div>
</div>
<p>Jython will start scanning for .pyc files in your path and if it finds one, will use the .pyc file to load you
module. .pyc files are the files that CPython produces when it compiles Python source code. So, if you after
you have imported pycimport (which adds a hook to sys.meta_path) then issue:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">foo</span>
</pre></div>
</div>
<p>Jython will scan your path for a file named foo.pyc, and if it finds one it will import the foo module using the
CPython bytecodes.  Here the code at the bottom of pycimport.py that makes defines the MetaImporter and adds
it to sys.meta_path:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">__MetaImporter</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">__importers</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="k">def</span> <span class="nf">find_module</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fullname</span><span class="p">,</span> <span class="n">path</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">__debugging__</span><span class="p">:</span> <span class="k">print</span> <span class="s">&quot;MetaImporter.find_module(</span><span class="si">%s</span><span class="s">, </span><span class="si">%s</span><span class="s">)&quot;</span> <span class="o">%</span> <span class="p">(</span>
            <span class="nb">repr</span><span class="p">(</span><span class="n">fullname</span><span class="p">),</span> <span class="nb">repr</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>
        <span class="k">for</span> <span class="n">_path</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">_path</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">__importers</span><span class="p">:</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">__importers</span><span class="p">[</span><span class="n">_path</span><span class="p">]</span> <span class="o">=</span> <span class="n">__Importer</span><span class="p">(</span><span class="n">_path</span><span class="p">)</span>
                <span class="k">except</span><span class="p">:</span>
                    <span class="bp">self</span><span class="o">.</span><span class="n">__importers</span><span class="p">[</span><span class="n">_path</span><span class="p">]</span> <span class="o">=</span> <span class="bp">None</span>
            <span class="n">importer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">__importers</span><span class="p">[</span><span class="n">_path</span><span class="p">]</span>
            <span class="k">if</span> <span class="n">importer</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
                <span class="n">loader</span> <span class="o">=</span> <span class="n">importer</span><span class="o">.</span><span class="n">find_module</span><span class="p">(</span><span class="n">fullname</span><span class="p">,</span> <span class="n">path</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">loader</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span><span class="p">:</span>
                    <span class="k">return</span> <span class="n">loader</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="k">return</span> <span class="bp">None</span>

<span class="n">sys</span><span class="o">.</span><span class="n">meta_path</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mf">0</span><span class="p">,</span> <span class="n">__MetaImporter</span><span class="p">())</span>
</pre></div>
</div>
<p>The find_module method calls into other parts of pycimport and looks for .pyc files. If it finds one,
it knows how to parse and execute those files and adds the corresponding module to the runtime. Pretty cool eh?</p>
</div>
</div>
<div class="section" id="java-package-scanning">
<h2>Java Package Scanning<a class="headerlink" href="#java-package-scanning" title="Permalink to this headline"></a></h2>
<p>Although you can ask the Java SDK to give you a list of all of the packages known to a ClassLoader using:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">java</span><span class="o">.</span><span class="n">lang</span><span class="o">.</span><span class="n">ClassLoader</span><span class="c">#getPackages()</span>
</pre></div>
</div>
<p>there is no corresponding</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">java</span><span class="o">.</span><span class="n">lang</span><span class="o">.</span><span class="n">Package</span><span class="c">#getClasses()</span>
</pre></div>
</div>
<p>This is unfortunate for Jython, because Jython users expect to be able to introspect they code they
use in powerful ways. For example, users expect to be able to call dir() on Java objects and packages
to see what names they contain:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">java.util.zip</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">(</span><span class="n">java</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">zip</span><span class="p">)</span>
<span class="go">[&#39;Adler32&#39;, &#39;CRC32&#39;, &#39;CheckedInputStream&#39;, &#39;CheckedOutputStream&#39;, &#39;Checksum&#39;, &#39;DataFormatException&#39;, &#39;Deflater&#39;, &#39;DeflaterOutputStream&#39;, &#39;GZIPInputStream&#39;, &#39;GZIPOutputStream&#39;, &#39;Inflater&#39;, &#39;InflaterInputStream&#39;, &#39;ZipEntry&#39;, &#39;ZipException&#39;, &#39;ZipFile&#39;, &#39;ZipInputStream&#39;, &#39;ZipOutputStream&#39;, &#39;__name__&#39;]</span>
<span class="gp">&gt;&gt;&gt; </span><span class="nb">dir</span><span class="p">(</span><span class="n">java</span><span class="o">.</span><span class="n">util</span><span class="o">.</span><span class="n">zip</span><span class="o">.</span><span class="n">ZipInputStream</span><span class="p">)</span>
<span class="go">[&#39;__class__&#39;, &#39;__delattr__&#39;, &#39;__doc__&#39;, &#39;__eq__&#39;, &#39;__getattribute__&#39;, &#39;__hash__&#39;, &#39;__init__&#39;, &#39;__ne__&#39;, &#39;__new__&#39;, &#39;__reduce__&#39;, &#39;__reduce_ex__&#39;, &#39;__repr__&#39;, &#39;__setattr__&#39;, &#39;__str__&#39;, &#39;available&#39;, &#39;class&#39;, &#39;close&#39;, &#39;closeEntry&#39;, &#39;equals&#39;, &#39;getClass&#39;, &#39;getNextEntry&#39;, &#39;hashCode&#39;, &#39;mark&#39;, &#39;markSupported&#39;, &#39;nextEntry&#39;, &#39;notify&#39;, &#39;notifyAll&#39;, &#39;read&#39;, &#39;reset&#39;, &#39;skip&#39;, &#39;toString&#39;, &#39;wait&#39;]</span>
</pre></div>
</div>
<p>To make this sort of introspection possible in the face of merged namespaces requires some major effort the
first time that Jython is started (and when jars or classes are added to Jython&#8217;s path at runtime). If
you have ever run a new install of Jython before, you will recognize the evidence of this system at work:</p>
<div class="highlight-python"><pre>*sys-package-mgr*: processing new jar, '/Users/frank/jython/jython.jar'
*sys-package-mgr*: processing new jar, '/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/classes.jar'
*sys-package-mgr*: processing new jar, '/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/ui.jar'
*sys-package-mgr*: processing new jar, '/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Classes/laf.jar'
...
*sys-package-mgr*: processing new jar, '/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home/lib/ext/sunjce_provider.jar'
*sys-package-mgr*: processing new jar, '/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home/lib/ext/sunpkcs11.jar'</pre>
</div>
<p>This is Jython scanning all of the jar files that it can find to build an internal representation of the
package and classes available on your  JVM. This has the unfortunate side effect of making the first startup
on a new Jython installation painfully slow.</p>
<div class="section" id="how-jython-finds-the-jars-and-classes-to-scan">
<h3>How Jython Finds the Jars and Classes to scan<a class="headerlink" href="#how-jython-finds-the-jars-and-classes-to-scan" title="Permalink to this headline"></a></h3>
<p>There are two properties that Jython uses to find jars and classes. These settings can be given to Jython
using commandline settings or the registry (see Chapter XXX). The two properties are:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="n">python</span><span class="o">.</span><span class="n">packages</span><span class="o">.</span><span class="n">paths</span>
<span class="n">python</span><span class="o">.</span><span class="n">packagse</span><span class="o">.</span><span class="n">directories</span>
</pre></div>
</div>
<p>These properties are comma separated lists of further registry entries that actually contain the values
the scanner will use to build its listing. You probably should not change these properties. The properties
that get pointed to by these properties are more interesting. The two that potentially make sense to manipulate are:</p>
<div class="highlight-python"><pre>java.class.path
java.ext.dirs</pre>
</div>
<p>For the java.class.path property, entries are separated as the classpath is separated on the operating
system you are on (that is, &#8220;;&#8221; on Windows and &#8220;:&#8221; on most other systems).  Each of these paths are checked
for a .jar or .zip and if they have these suffixes they will be scanned.</p>
<p>For the java.ext.dirs property, entries are separated in the same manner as java.class.path, but these
entries represent directories.  These directories are searched for any files that end with .jar or .zip,
and if any are found they are scanned.</p>
<p>To control the jars that are scanned, you need to set the values for these properties. There are a number
of ways to set these property values, see Chapter XXX for more.</p>
<p>If you only use full class imports, you can skip the package scanning altogether. Set the system property
python.cachedir.skip to true or(again) pass in your own postProperties to turn it off.</p>
</div>
</div>
<div class="section" id="python-modules-and-packages-vs-java-packages">
<h2>Python Modules and Packages vs. Java Packages<a class="headerlink" href="#python-modules-and-packages-vs-java-packages" title="Permalink to this headline"></a></h2>
<p>The basic semantics of importing Python modules and packages versus the semantics of importing Java packages
into Jython differ in some important respects that need to be kept carefully in mind.</p>
<div class="section" id="sys-path">
<h3>sys.path<a class="headerlink" href="#sys-path" title="Permalink to this headline"></a></h3>
<p>When Jython tries to import a module, it will look in its sys.path in the manner described in the
previous section until it finds one. If the module it finds represents a Python module or package,
this import will display a “winner take all” semantic. That is, the first python module or package that
gets imported blocks any other module or package that might subsequently get found on any lookups. This
means that if you have a module foo that contains only a name bar early in the sys.path, and then another
module also called foo that only contains a name baz, then executing “import foo” will only give you
foo.bar and not foo.baz.</p>
<p>This differs from the case when Jython is importing Java packages. If you have a Java package org.foo
containing bar, and a Java package org.foo containing baz later in the path, executing “import org.foo”
will merge the two namespaces so that you will get both org.foo.bar and org.foo.baz.</p>
<p>Just as important to keep in mind, if there is a Python module or package of a particular name in
your path that conflicts with a Java package in your path this will also have a winner take all effect.
If the Java package is first in the path, then that name will be bound to the merged Java packages.
If the Python module or package wins, no further searching will take place, so the Java packages
with the clashing names will never be found.</p>
</div>
<div class="section" id="naming-python-modules-and-packages">
<h3>Naming Python Modules and Packages<a class="headerlink" href="#naming-python-modules-and-packages" title="Permalink to this headline"></a></h3>
<p>Developers coming from Java will often make the mistake of modeling their Jython package structure the
same way that they model Java packages. Do not do this. The reverse url convention of Java is a great,
I would even say a brilliant convention for Java. It works very well indeed in the world of Java where
these namespaces are merged. In the Python world however, where modules and packages display the winner
take all semantic, this is a disastrous way to organize your code.</p>
<p>If you adopt this style for Python, say you are coming from “acme.com” so you would set up a package
structure like “com.acme”. If you try to use a library from your vendor xyz that is set up as “com.xyz”,
then the first of these on your path will take the “com” namespace, and you will not be able to see
the other set of packages.</p>
</div>
<div class="section" id="proper-python-naming">
<h3>Proper Python Naming<a class="headerlink" href="#proper-python-naming" title="Permalink to this headline"></a></h3>
<p>The Python convention is to keep namespaces as shallow as you can, and make your top level namespace reasonably
unique, whether it be a module or a package. In the case of acme and company xyz above, you might start you package
structures with “acme” and “xyz” if you wanted to have these entire codebases under one namespace (not necessarily
the right way to go – better to organize by product instead of by organization, as a general rule).</p>
<p>Note: There are at least two sets of names that are particularly bad choices for naming modules or packages
in Jython. The first is any top level domain like org, com, net, us, name. The second is any of the domains
that Java the language has reserved for its top level namespaces: java, javax.</p>
</div>
<div class="section" id="java-import-example">
<h3>Java Import Example<a class="headerlink" href="#java-import-example" title="Permalink to this headline"></a></h3>
<p>We&#8217;ll start with a Java class which is on the CLASSPATH when Jython is started:</p>
<div class="highlight-python"><pre>package com.foo;
public class HelloWorld {
    public void hello() {
        System.out.println("Hello World!");
    }
    public void hello(String name) {
        System.out.printf("Hello %s!", name);
    }
}</pre>
</div>
<p>Here we manipulate that class from the Jython interactive interpreter:</p>
<div class="highlight-python"><div class="highlight"><pre><span class="gp">&gt;&gt;&gt; </span><span class="kn">from</span> <span class="nn">com.foo</span> <span class="kn">import</span> <span class="n">HelloWorld</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">h</span> <span class="o">=</span> <span class="n">HelloWorld</span><span class="p">()</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">h</span><span class="o">.</span><span class="n">hello</span><span class="p">()</span>
<span class="go">Hello World!</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">h</span><span class="o">.</span><span class="n">hello</span><span class="p">(</span><span class="s">&quot;frank&quot;</span><span class="p">)</span>
<span class="go">Hello frank!</span>
</pre></div>
</div>
<p>It&#8217;s important to note that, because the HelloWorld program is located on the Java CLASSPATH, it did not go
through the sys.path process we talked about before. In this case the Java class gets loaded directly by the
ClassLoader.  Discussions of Java ClassLoaders are beyond the scope of this book.  To read more about ClassLoader
see (citation? Perhaps point to the Java Language Specification section)</p>
</div>
</div>
<div class="section" id="conclusion">
<h2>Conclusion<a class="headerlink" href="#conclusion" title="Permalink to this headline"></a></h2>
<p>In this chapter we have learned how to divide code up into modules to for the purpose of organization and re-use.
We have learned how to write modules and packages, and how the Jython system interacts with Java classes and packages.
This ends Part I.  We have now covered the basics of the Jython language and are now ready to learn how to use Jython.</p>
</div>
</div>


          </div>
        </div>
      </div>
      <div class="sphinxsidebar">
        <div class="sphinxsidebarwrapper">
            <h3><a href="index.html">Table Of Contents</a></h3>
            <ul>
<li><a class="reference external" href="">Chapter 7: Modules and Packages</a><ul>
<li><a class="reference external" href="#imports-for-re-use">Imports For Re-Use</a><ul>
<li><a class="reference external" href="#definitions">Definitions</a></li>
<li><a class="reference external" href="#the-import-statement">The Import Statement</a></li>
<li><a class="reference external" href="#an-example-program">An Example Program</a></li>
</ul>
</li>
<li><a class="reference external" href="#types-of-import-statements">Types of import statements</a><ul>
<li><a class="reference external" href="#relative-import-statements">Relative import Statements</a></li>
<li><a class="reference external" href="#aliasing-import-statements">Aliasing import Statements</a></li>
<li><a class="reference external" href="#hiding-module-names">Hiding Module Names</a></li>
</ul>
</li>
<li><a class="reference external" href="#module-search-path-compilation-and-loading">Module Search Path, Compilation, and Loading</a><ul>
<li><a class="reference external" href="#compilation">Compilation</a></li>
<li><a class="reference external" href="#module-search-path-and-loading">Module search Path and Loading</a></li>
<li><a class="reference external" href="#import-hooks">Import Hooks</a></li>
<li><a class="reference external" href="#sys-meta-path">sys.meta_path</a></li>
</ul>
</li>
<li><a class="reference external" href="#java-package-scanning">Java Package Scanning</a><ul>
<li><a class="reference external" href="#how-jython-finds-the-jars-and-classes-to-scan">How Jython Finds the Jars and Classes to scan</a></li>
</ul>
</li>
<li><a class="reference external" href="#python-modules-and-packages-vs-java-packages">Python Modules and Packages vs. Java Packages</a><ul>
<li><a class="reference external" href="#sys-path">sys.path</a></li>
<li><a class="reference external" href="#naming-python-modules-and-packages">Naming Python Modules and Packages</a></li>
<li><a class="reference external" href="#proper-python-naming">Proper Python Naming</a></li>
<li><a class="reference external" href="#java-import-example">Java Import Example</a></li>
</ul>
</li>
<li><a class="reference external" href="#conclusion">Conclusion</a></li>
</ul>
</li>
</ul>

            <h4>Previous topic</h4>
            <p class="topless"><a href="chapter6.html"
                                  title="previous chapter">Chapter 6:  Object Oriented Jython</a></p>
            <h4>Next topic</h4>
            <p class="topless"><a href="chapter8.html"
                                  title="next chapter">Chapter 8:  Scripting with Jython</a></p>
            <h3>This Page</h3>
            <ul class="this-page-menu">
              <li><a href="_sources/chapter7.txt"
                     rel="nofollow">Show Source</a></li>
            </ul>
          <div id="searchbox" style="display: none">
            <h3>Quick search</h3>
              <form class="search" action="search.html" method="get">
                <input type="text" name="q" size="18" />
                <input type="submit" value="Go" />
                <input type="hidden" name="check_keywords" value="yes" />
                <input type="hidden" name="area" value="default" />
              </form>
              <p class="searchtip" style="font-size: 90%">
              Enter search terms or a module, class or function name.
              </p>
          </div>
          <script type="text/javascript">$('#searchbox').show(0);</script>
        </div>
      </div>
      <div class="clearer"></div>
    </div>
    <div class="related">
      <h3>Navigation</h3>
      <ul>
        <li class="right" style="margin-right: 10px">
          <a href="genindex.html" title="General Index"
             >index</a></li>
        <li class="right" >
          <a href="chapter8.html" title="Chapter 8: Scripting with Jython"
             >next</a> |</li>
        <li class="right" >
          <a href="chapter6.html" title="Chapter 6: Object Oriented Jython"
             >previous</a> |</li>
        <li><a href="index.html">Jython Book v0.1 documentation</a> &raquo;</li> 
      </ul>
    </div>
    <div class="footer">
      &copy; Copyright 2009, Josh Juneau, Frank Wierzbicki, Jim Baker, Leo Soto, ViVictor Ng.
      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 0.6.1.
    </div>
  </body>
</html>