Is count supposed to still work?

Bengt Richter bokr at oz.net
Sat Jul 13 16:33:58 EDT 2002


On Fri, 12 Jul 2002 13:17:56 -0700, "David LeBlanc" <whisper at oz.net> wrote:

>Whether or not you explicitly import string,

>	count(mystring, substring)
>isn't working ("NameError: global name 'count' is not defined") (N.B. this
>statement is in a method of a class),
If you want the global name "count" to mean the string.count function,

    from string import count
or
    import string
    count = string.count
or (not recommended! -- perhaps you got that in previous code and got the impression count was a builtin?)
    from string import * # name collision risk

or bind global count to the count method of str, whose usage looks the same
    count = str.count

Or you could derive your class from str, and access count as your own method:
 >>> class Foo(str):
 ...     def bar(self, substr):
 ...         return self.count(substr)
 ...
 >>> foo = Foo('hi ho hum hip hop hello')
 >>> foo.bar('hi')
 2
 >>> foo.bar('h')
 6

You could also bind str.count inside a method for local reference, e.g.,
 >>> class Foo:
 ...     def __init__(self, s): self.s = s
 ...     def bar(self, ss, count=str.count):
 ...         return count(self.s, ss)
 ...
 >>> foo = Foo('hi ho hum hip hop hello')
 >>> foo.bar('hi')
 2

<related idea>
I (think I ;-) wish there were a way to declare a function variable local, global, or
inbetween _explicitly_, as opposed to a global/local binary choice side effect
of a first reference's being an "assignment."  It could default to the current way,
but then you could do something like

class Foo:  # make-believe example
    def __init__(self, s): self.s = s
    def bar(self, ss):
        set_scope('count')  # (not currently implemented. Default scope 0 == local, -1  most global)
        return count(self.s, ss)       # ref to count would _not_ assume global here
    bar.count=str.count                # would initialize the local-to-bar count as it now does

the idea being that you could refer to nested scopes by nesting level outward, or from the outermost
global scope inward by negative indices, as if referring to a list of directories forming a namespace.
Thus the current "global x" would functionally equal "set_scope('x', -1)". And set_scope('var_name', 1)
would  let you rebind in an enclosing scope (not necessarily immediately enclosing, as with level 1),
and the list of nested scopes would allow systematic nested name search.

set_scope might be defined with default parameters, e.g.,
    def set_scope(name, level=0, namespace=None): ...
where namespace=None would signify current lexical scope, but other specs for a level 0 starting
point would be possible, e.g., self might imply [instance, class, ... builtin, global] as the nest
search sequence.
(For discussion only. Usual OTTOMH caveats apply ;-)
</related idea>


>but
>	mystring.count(substring)
>does. However, count is not listed as deprecated in the python 2.2.1 doc.
>Even deprecated, it should still work.
>
>FWIW, I wish none of these where deprecated. Maybe it's incorrect, but I
>tend to think of an attribute of something, not something's attribute. Both
>ways are useful IMO. Sometimes len|count|int|float(thing) is nice and
>sometimes
>thing.len|count|int|float() works better. Not a different way to do
>something, a different way to express the same thing.
>
But if built-in functions like that accumulated indefinitely, we'd have a
very cluttered name space, so while I agree that some are nice, I'd rather
have an efficient way to import and bind what I need than have clutter.

Regards,
Bengt Richter



More information about the Python-list mailing list