Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #76433 > unrolled thread
| Started by | Chris Angelico <rosuav@gmail.com> |
|---|---|
| First post | 2014-08-18 01:15 +1000 |
| Last post | 2014-08-18 02:20 +1000 |
| Articles | 3 — 2 participants |
Back to article view | Back to comp.lang.python
Module-level functions and the module type Chris Angelico <rosuav@gmail.com> - 2014-08-18 01:15 +1000
Re: Module-level functions and the module type Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-08-18 01:59 +1000
Re: Module-level functions and the module type Chris Angelico <rosuav@gmail.com> - 2014-08-18 02:20 +1000
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-08-18 01:15 +1000 |
| Subject | Module-level functions and the module type |
| Message-ID | <mailman.13070.1408288560.18130.python-list@python.org> |
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?
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()
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?
ChrisA
[toc] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2014-08-18 01:59 +1000 |
| Message-ID | <53f0d167$0$29976$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #76433 |
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@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
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-08-18 02:20 +1000 |
| Message-ID | <mailman.13075.1408292414.18130.python-list@python.org> |
| In reply to | #76436 |
On Mon, Aug 18, 2014 at 1:59 AM, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> wrote:
> 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)
I agree with this, and the C++ way of doing things is fraught with
peril. The only way it could even possibly work is with fully-declared
instance variables, and that's something Python's not going for :)
However, there's no particular reason not to have 'self' as a special
name. It's already pretty much reserved for that by convention, so
this would just mean that, in a module with an explicit metaclass,
'self' refers to the module object. You'd get something like this:
def method():
a = self.b + len(c)
which, after all, isn't materially different from your third entry, in
that both of them need some kind of implicit namespace, just as your
explicit 'this' example from above does.
Since this would then also be at module level, it would be reasonable
for 'global x' to correspond to 'self.x', which is something that
would require a bit more language support. Currently, the version I
demonstrated has an extra level of namespacing, which is completely
unnecessary. It'd be nice to be able to unify all of that.
ChrisA
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web