On 03/16/2013 03:04 PM, [email protected] wrote:
Dear Tutor

Global constants and variables are bad.

First, let me define my own "rule." Global constants should be all uppercase, and global variables should be avoided. Trivial and buggy scripts may ignore both rules. A trivial script is typically anything under 30 lines. Buggy scripts are those which you delete as soon as you ran them once.

So what's a global constant? It's something that's set once, soon after the script starts, and *usually* not changed later in the run. For example, cmdline arguments and things directly derived from them. Special numbers (such as math.pi which is global in that module, and should have been capitalized). OS-specific details.

But what's better? I've heard some
suggestions, but haven't seen much actual code showing how to improve globals. I
don't like:

* Passing a lot of individual arguments.


I don't know how many you consider 'a lot.' Consider factoring the function into simpler components.

* Creating a structure with unrelated elements.

Presumably you mean a class instance with unrelated attributes. And yes, certainly if you're creating a singleton class just as a holder for a pile of globals, then you might as well use the globals() collection in a given module. rather than writing your own. On the other hand, things that are unrelated in one context may very well be related in another. Smart dividing up of the problem is one of the things that helps makes code readable and reusable.

* Passing a structure, as an argument, through a function that uses only one (or
none of the) elements in the structure.

Here, I have to disagree entirely. If the class is intelligently designed, the instance is holding a bunch of interconnected data. If the function needs one thing from it, no harm done passing the whole instance.

An example is a gui 'listbox' instance. It has lots of data that the gui will use in painting it, positioning it, and generating events about it. But an individual portion of the code may be only interested in the selected item in the list, not in the title, nor the horizontal size, nor ...


I created an example (below), that could be written with global constants and
variables. How would you suggest handling something like this? (I don't need you
to stick to my example.)

#!/usr/bin/python

START = '<'
END = '>'

def getargs():
     getops()
     if
         in_filename_1 =
         in_filename_2 =
         out_filename_1 =
         out_filename_2 =
         flag1 =
         verbose =

Take a look at the modules in the standard library that do this sort of thing. They return an object which contains all the parsed parameters.


def this():
     open_for_read()
     stuff()

And if you decide to open two files instead of one, and process them both in a similar way? Suddenly you'll need to pass a filename into this function. Why not start that way, so the function is readable?


def open_for_read(filename):
     in_filehandle = open(
     return in_filehandle

Looks good.

def stuff():

  def  stuff(c, foo):

""" interpret the character c and set the flag that will control how the rest of the program works
       """
     if c == START or c == END:
         foo_the_bar =
       if c in START+END:
           foo.BAR =

def that():
     things()
     write_status(out_filename_1)

Why are these in one function, if they're unrelated?


The rest of the examples were too abstracted to be able to comment on.

def things():
     bar_the_foo = foo_the_bar
     if verbose:
         print(flag1)

def write_status(out_filename_1):

getargs()
this()
that()


I very much appreciate the help that you have given me!

Thanks
Ken


When you start writing code that's big enough to have reusable pieces, you'll begin to appreciate how writing parameterized code makes it more reusable. And when you try to debug stuff where a change in one function's use of a global breaks another function far away, you'll start to appreciate how it's handy to have each function have a (somewhat) reduced space it can damage, or be damaged by.

My biggest disasters were "trivial" programs that grew beyond their original scope, and I never changed the mindset in rewriting them. I had once such program recently which had many authors and was a real mess. (Besides, it was written in perl, which it makes it much easier to write unmaintainable hacks) I wanted to make a substantial change and wound up writing a new program that invoked the first. That first couldn't walk on my globals once it was in a separate process.


--
DaveA
_______________________________________________
Tutor maillist  -  [email protected]
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to