Storing objects required by functions.

Terry Reedy tjreedy at udel.edu
Tue Dec 30 12:43:13 EST 2003


"David M. Wilson" <dw-google.com at botanicus.net> wrote in message
news:99dce321.0312300655.14c5a8db at posting.google.com...
> Further to my last post here, I was playing some more with building a
> regex object and storing it somewhere for use internally by a
> function. I'm not happy with any of my solutions:

> # I don't like this, but the fact that you can modify the procedure's
> # function via a named argument seems neat in a hacky sort of way.
>
> def uses_default_parm_yuck(x, r = re.compile("...")):
>     pass

I default args less bothersome than some people.  The only problem for me
is that a caller may accidentally give nonesense second param.  If this can
silently give a junk answer, this is not very acceptable.  In this case,
random objects without a match() method would raise an exception.

> g = re.compile('...')

Use _ to indicate 'private' or 'local-use-only' status.

_hex = re.compile()

> def uses_global_yuck(x):
>     global g
>     pass

The global declaration is not needed for read-only access and is therefore
misleading. So delete and just use _hex in the body.  Python functions
constantly use globals and builtins, both functions and other values, in
read-only mode.  So I see no problem with this standard Python idiom.

> # This is horrible and probably slow.
>
> class is_hex:
>     def __init__(self):
>         self.r = re.compile('...')
>
>     def __call__(self, x):
>         r = self.r
>         pass

One should at least generalize this to re_matcher and pass specific re to
init.  OO purists might prefer this but I agree that it is overkill unless,
possibly, one has lots of instances.  OO was made for man, not man for OO
purity.

> is_hex = is_hex()

is_hex = re_matcher(hex_re)

> # This mucks up scoping so that your procedure can't access it's
> # parent scope like it could normally.

Funny, you just objected above to having a function access is parent scope
for the re.

> def is_hex():
>     r = re.compile('...')
>     def is_hex(s):
>         return r.match(s) is not None
>     return is_hex

> is_hex = is_hex()

Same comment: generalize

def re_matcher(some_re):
   r = re.compile(some_re)
  def is_some(s):
    return r.match(s) is not None
  return is_some

is_hex = re_matcher(hex_re)

I would use this in preverence to class version for making multiple
matchers.  I think closures are great as one-method instances (or as
callable no-method instances, if one prefers).

Terry J. Reedy






More information about the Python-list mailing list