[Python-ideas] anonymous object support

Nick Coghlan ncoghlan at gmail.com
Tue Jul 26 06:06:00 CEST 2011


On Tue, Jul 26, 2011 at 12:58 PM, Herman Sheremetyev
<herman at swebpage.com> wrote:
> Well, I think it's not very intuitive that type() can be used as a
> class constructor.

Then you don't really understand metaclasses yet (now, metaclasses
themselves certainly don't qualify as intuitive, but understanding
them is essential to understanding many otherwise confusing elements
of Python's type system). type() works the way it does because it is
designed to construct a new class object from a name, a tuple of base
classes and a namespace dictionary, just like any other metaclass. The
slightly hacky (but very convenient) part is actually the ability to
use the single argument form of type() to query the metaclass of an
existing object.

To get back to the ideas discussed in this thread:

1. Use cases where creating a lot of one-shot classes on the fly is a
reasonable idea are rare and highly specialised
2. If you want to do so, the obvious way is to use a class statement
and adjust __name__ and __dict__ afterwards
3. Alternatively, if you want this functionality as an expression,
either the type builtin or a custom function can do the job
4. It is significantly more efficient to abstract out a common class
definition and create multiple instances of that class
5. If you just want a namespace to store some data with consistent
attribute names, then collections.namedtuple can be used to also make
the instance storage efficient. If you store a function in a
namedtuple instance then you can still call it, it just won't be
passed 'self' as an implicit first parameter (as the descriptor
machinery will not be invoked).
6. If you just want an arbitrary attribute holder, than instances of a
trivial empty user-defined class can serve that purpose. As with named
tuples, functions stored on the instance can still be called, but
retrieving them won't invoke the descriptor machinery.
7. Mock objects do *not* qualify as a common use case. Despite the
proliferation of libraries that choose to provide slightly different
APIs for them, such objects may be used widely in test suites but are
still *implemented* rarely - they fall into the "highly specialised"
category I mentioned above.

The tools are there so that people that know what they're doing can do
what needs to be done to achieve their ends. Simplifying the API for
dynamic type creation would be an attractive nuisance, as it will
likely lead to people writing ill-advised code without giving the
matter sufficient thought. Obviously, that's going to happen no matter
what we do, but there's no reason for us to deliberately *encourage*
bad ideas by making them too easy to write.

Points 5 and 6 go back to the original question about namespace
objects, which is independent of the dynamic type creation issue.
Various attempts have been made to address that over the years, and
the current answers are the original approach (just define a namespace
type and use instances of it to store arbitrary data, with poor
debugging support due to the relative anonymity and arbitrary content
of each instance) and the named tuple approach, which provides
excellent debugging information and memory efficiency at the cost of
being explicit up front regarding the attributes possessed by each
instance.

Regards,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list