On Wed, May 06, 2020 at 09:17:15PM -0400, Eric V. Smith wrote:
> I think David is right: itertools.chain.from_iterable() is the only
> place I know of with an attribute on a function that's another function.
Functions decorated with `functools.wrap` have an attribute that gives
the original function:
py> def f(): return True
...
py> g = wraps(f)(lambda: False)
py> g()
False
py> g.__wrapped__()
True
Likewise `functools.partial` objects have a `func` attribute that gives
the original function:
py> h = partial(lambda a, b: a + b)
py> h = partial(lambda a, b: a + b, 1000)
py> h(1)
1001
py> h.func(1, 2)
3
Functions which have been decorated with lru_cache are given two
function attributes, `cache_clear` and `cache_info`.
I believe that there is also an example in mock, but I don't remember
the details.
I wanted to use this attributes on the median() function in the
statistics module to spell the less-important variations:
median() # standard version as taught in schools
with the specialist versions as attributes:
median.lower()
median.upper()
but I was talked out of it in favour of three separate functions:
median, median_lower, median_upper
I still regret giving in on this point. IMO the lower and upper medians
are useful but not important enough to be top-level functions.
"Namespaces are one honking great idea -- let's do more of those!"
Functions are namespaces! They have internal `__dicts__` and can hold
arbitrary attributes. Why are we so reluctant to follow the Zen and use
those namespaces?
> Alternate constructors are generally classmethods.
The fact that chain.from_iterable is, in a sense, an alternative
constructor is an implementation detail. `chain` happens to be a class
that returns an instance of `chain`, but it could have simply returned a
generic generator, or some other kind of instance.
> And it's the documentation that I'm concerned about: I don't think
> itertools.chain.from_iterable() is very discoverable. Plenty of people
> don't know it exists. That's my concern with this approach.
It isn't hard to add a "See also..." line to the chain docstring
pointing to the existence of chain.from_iterable, and we should do that.
Also, help() should be enhanced to give better support for function
attributes.
Your point about discoverability is taken, but it is no less
discoverable than other namespaces. If I know a package:
import package
package.function(arg)
that knowledge doesn't give me any insight into any subpackages that I
haven't imported and may not even know about:
# How do I learn to do this?
from package.subpackage import anotherfunction
--
Steven
_______________________________________________
Python-ideas mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at
https://mail.python.org/archives/list/[email protected]/message/QTDBXD733BL2AFYG7V6IPAJ5BG7T42VF/
Code of Conduct: http://python.org/psf/codeofconduct/