Module-level functions and the module type
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Sun Aug 17 11:59:34 EDT 2014
Chris Angelico wrote:
> In a class definition, you have explicit state parameters on your
> functions - 'self':
>
> class C:
> def foo(self, arg):
> # blah blah
>
> At module level, there's equivalent state - the function "knows" what
> module it came from - but it's implicit:
>
> def foo(arg):
> # blah blah
>
> print(foo.__globals__)
>
> How hard would it be to unify these, and make modules into classes?
There's a difference though: modules are instances of ModuleType. While it's
true that classes are instances of type, you cannot instantiate a module
instance.
> This would then allow stuff like properties, metaclasses, and so on,
> all with exactly the same semantics as they have in classes.
>
> Obviously this would be a huge backward-compatibility break if it
> happened everywhere, but what I'm looking at here is a way to
> basically bless this kind of concept:
>
> # spam.py
> class RealSpam:
> # module contents here
>
> import sys
> sys.modules[__name__] = RealSpam()
But that is already blessed! You can stick anything you like in sys.modules,
and import will accept it. This is been true for a long time:
[steve at ando ~]$ python2.4
Python 2.4.3 (#1, Jan 9 2013, 06:49:54)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-54)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
py> import sys
py> sys.modules['lunch'] = 'spam spam spam'
py> import lunch
py> lunch.upper()
'SPAM SPAM SPAM'
There is a special meaning to given to None:
py> sys.modules['breakfast'] = None
py> import breakfast
Traceback (most recent call last):
File "<stdin>", line 1, in ?
ImportError: No module named breakfast
but otherwise you should be able to use anything you like. The tricky part
is having a module replace itself on the fly.
> So the question is: Why is state implicit in one and explicit in the
> other? Which option is really the better way to do things?
Global state is implicit so that we can write code with unqualified variable
names, and the current namespace is implicit:
# Module m.py
x = 1
y = x + 1
instead of this:
this.x = 1
this.y = this.x + 1
Also, the interpreter would need to handle "this" specially, it can't just
be a regular variable. If it was, you would need to look it up in an
explicitly stated namespace, which is an ordinary variable that needs a
namespace...
x # Where's the namespace for x?
this.x # Where's the namespace for this?
this.this.x
this.this.this.x
this.this.this.this.x
...
*Somewhere* there has to be an implicit namespace. Might as well be right at
the beginning.
But inside class methods we have a problem:
class X:
def method():
a = b + c
We can trivially decide on a rule that a must be a local, but how about b
and c? Are they globals or attributes of the instance? Python decided on
giving globals (well, actually nonlocals) priority, and requiring an
explicit self, so we can write this:
def method(self):
a = self.b + len(c)
instead of this:
def method():
locals.a = b + globals.len(globals.c)
--
Steven
More information about the Python-list
mailing list