[Tutor] Modularity

James Chapman james at uplinkzero.com
Thu Jan 14 05:01:04 EST 2016


May I suggest: https://docs.python.org/2/tutorial/modules.html

In particular:
* https://docs.python.org/2/tutorial/modules.html#the-module-search-path
* https://docs.python.org/2/tutorial/modules.html#packages


Now the next bit of advice is likely to be controversial but I have
good reasons for it.

I like to import the top level module and use the full namespace in
the code, that way, when I come back to it in 3 years time I know
where each function call is coming from.

For example, lets say I had the following package (stolen from the
docs page linked above):


sound/                          Top-level package
      __init__.py               Initialize the sound package
      formats/                  Subpackage for file format conversions
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  Subpackage for sound effects
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  Subpackage for filters
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py


I myself would import as follows

        import sound

Then in my code, the calls would look like:

        wave = sound.formats.waveread(someFile)
        aiffFile = sound.formats.aiffwrite(wave)
        auFile = sound.formats.auwrite(wave)


If I did:

        from sound import formats.*

Then the code would be

        wave = waveread(someFile)
        aiffFile = aiffwrite(wave)
        auFile = auwrite(wave)


The problem with the latter is, which module supplies waveread?
I have roughly 20 import statements where I'm importing something.*
which one of those modules supplies the function waveread?


A way around the above would be

        import sound.formats.waveread
        import sound.formats.aiffwrite
        import sound.formats.auwrite

Code would then be

        wave = waveread(someFile)
        aiffFile = aiffwrite(wave)
        auFile = auwrite(wave)



But what if we have various modules that implement a waveread function?

Then we'd have to start using

        import sound.formats.waveread as sfwaveread
        import some.other.waveread


Code is read more than it is written, so don't be lazy! Use the
namespaces in your code. You make it clear what you're doing it you
avoid clashing.


Finally, if you absolutely must be lazy, then import like this:

        from sound import formats as sf

        wave = sf.waveread(someFile)
        aiffFile = sf.aiffwrite(wave)
        auFile = sf.auwrite(wave)


There is nothing I hate more than being asked to change or fix someone
elses code when that programmer is lazy and feels he/she can produce a
solution quicker by reducing the amount of typing he/she has to do.
Well, that's a lie, there are things I hate more but this come close!


James


More information about the Tutor mailing list