__module__ (was Re: Deprecate self)

Rainer Deyke root at rainerdeyke.com
Fri Apr 20 00:45:55 EDT 2001


"Alex Martelli" <aleaxit at yahoo.com> wrote in message
news:9bn4gu0ugt at news1.newsguy.com...
> "Rainer Deyke" <root at rainerdeyke.com> wrote in message
> news:vQpD6.47756$J%5.15806884 at news2.rdc2.tx.home.com...
>     [snip]
> > def f():
> >   class C:
> >     pass
> >   C()
>
> Ok, it's now clearer what you mean, thanks.  It doesn't
> STOP somebody sufficiently determined from subclassing
> it, of course:
>
> class OhYeah(f().__class__):
>     pass

Actually I'm not even returning an instance in my example, so even that
isn't possible.

> but it does provide a rather good hint that "being
> subclassed" is not the class's design intention:-).

> > This is, incidentially, the idiom I had to use extensively to deal with
> the
> > lack of nested scoping in Python.  More generally, you write a class for
>
> How does a local class help you there in ways nested
> scoping will make obsolete?  Sounds interesting.

def render(draw_fn):
  gc = get_gc()
  draw_fn(gc)

def render_text(text):
  class Text:
    def __init__(self, text):
      self.text = text
    def draw(gc):
      gc.draw_text(self.text)
  t = Text(text)
  render(t.draw)

In this case I could have used the default argument hack, but that isn't
generally applicable (think *args, **kwargs).

> > The benefit of singletons?  Consider the following module:
> >
> > # spam.py
> > def set_variable(name, value):
> >   do_something()
> >
> > def get_variable(name):
> >   return do_something_else()
> >
> > def del_variable(name):
> >   do_something_completely_different()
> >
> > To facilitate easier access to these functions, I introduce the
following
> > wrapper:
> >
> > class VariableAccess:
> >   def __setattr__(self, name, value):
> >     set_variable(name, value)
> >   def __getattr__(self, name):
> >     return get_variable(name)
> >   def __delattr__(self, name):
> >     return del_variable(name)
> > variables = VariableAccess()
> >
> >
> > Now the client can access the revealed variables through a more natural
> > interface.
>
> Nice -- a specifically Pythonic benefit.  Of course, it's no
> problem if VariableAccess gets multiply instantiated, so I
> would consider this an example of the pattern "Featherweight"
> (a class whose instances share all state) rather than one of
> the pattern "Singleton" (a class that is protected against
> being multiply instantiated), and I like FW as much as I
> dislike Singleton, so there's still no benefit to the singleton
> design pattern, but that's another issue.

There is no reason for multiply instantiating 'VariableAccess' because the
defining module provides one instance and every instance other instance is
identical in state and behavior.  Whether you call this a "Singleton" or a
"Featherweight" or even "Gorak, destroyer of worlds" is all the same to me.

> > Consider the following hypothetical Python-like language:
> >
> > def f():
> >   print 'spam'
> >
> > class C:
> >   def f(): # Note lack of 'self'
> >     print 'eggs'
> >   def g():
> >     __instance__.f()
> >     __module__.f()
> >
> > I'm not sure I like this myself (the __magic__ names are too long, the
> > result of a 'def' statement depends on context, there's no clear way to
> > refer to the outer class from a method in an inner class, magically
> > appearing variables have the potential to cause trouble, and the
> > 'C.f(instance_of_C)' conventions seems to be broken), but at least it's
> > better than the strawman against which you seem to have been arguing.
>
> Actually, I think _this_ is "a strawman proposal" -- one with some
> admitted defects but that at some level realizes design intentions.
> Earlier, I saw complaints but no pointer to resolving them.

My goal wasn't to change Python, but to discuss a perceived flaw in Python
which later generations of language designers would then be able to avoid
(or alternately to be convinced that the inconsistency is a good idea for
pragmatic reasons).

> Thanks for posting it at last.  I fully agree with all of your
> criticisms, and furthermore don't see how this will support the
> useful idiom of assigning an existing function to serve as a method,

Given this:

def f(x):
  do_something_width(x)

Instead of writing this:

class C:
  do_f = f

Write this:

class C:
  def do_f():
    __module__.f(__instance__) # Where '__module__.' might be optional.

This is assuming that you want the instance as first argument.  There are
times when you don't; see 'VariableAccessor' above.

> but then, pointing out such issues _IS_ a strawman proposal's role.
>
> I do see one nugget here -- allowing access to a module object
> through one of its own magic attributes may indeed be handier
> than using globals(), sys.modules[__name__], and other existing
> idioms.  The 'reference loop' it implies may be less terrible
> today (what with weak references, garbage collection, etc) than
> it may once have appeared.  Having each module object possess
> a __module__ attribute that references the object itself seems
> feasible, if the need to use that object is indeed frequent.
>
> A somewhat related issue is somehow getting easy access to the
> function object from that function's code -- particularly likely
> to be interesting now that function objects have arbitrary
> attributes.  Presumably harder as the __function__ (or
> whatever) would have to be stuck in (the locals...?).  Just
> an aside, anyway.

'__function__' could be treated similarily to default arguments.  I don't
see the problem.

> > I'm saying specifically that C++ is right in providing a way to qualify
> > names as global - no more.
>
> OK, I accept that's what you intended to say right from the
> start.  Now, "global" in C++ means "global across all sources"
> rather than "specific to this source".  Object specific to
> this module would be in the unnamed namespace (since the
> use of 'static' for that is [informally speaking only, I
> believe] deprecated in C++) and thus non-qualifiable; other
> (non-unnamed) namespaces are shared across sources.  Are
> you expressing admiration for THIS trait of C++?

No.  I see a certain advantage to C++'s decoupling of file and namespace,
but I am neither talking about it here, nor do I wish it upon Python.

>  Or do you
> actually wish to keep things Pythonically simple and is
> the C++ reference some sort of red herring?  It's starting
> to look that way to me.

Python is more than complex enough for me.


--
Rainer Deyke (root at rainerdeyke.com)
Shareware computer games           -           http://rainerdeyke.com
"In ihren Reihen zu stehen heisst unter Feinden zu kaempfen" - Abigor





More information about the Python-list mailing list