Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #110899 > unrolled thread
| Started by | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| First post | 2016-07-02 00:13 +1000 |
| Last post | 2016-07-09 07:05 -0700 |
| Articles | 16 on this page of 36 — 12 participants |
Back to article view | Back to comp.lang.python
Namespaces are one honking great idea Steven D'Aprano <steve@pearwood.info> - 2016-07-02 00:13 +1000
Re: Namespaces are one honking great idea Random832 <random832@fastmail.com> - 2016-07-01 10:40 -0400
Re: Namespaces are one honking great idea BartC <bc@freeuk.com> - 2016-07-01 15:49 +0100
Re: Namespaces are one honking great idea Chris Angelico <rosuav@gmail.com> - 2016-07-02 03:13 +1000
Re: Namespaces are one honking great idea Steven D'Aprano <steve@pearwood.info> - 2016-07-02 03:46 +1000
Re: Namespaces are one honking great idea Rustom Mody <rustompmody@gmail.com> - 2016-07-01 19:26 -0700
Re: Namespaces are one honking great idea Ethan Furman <ethan@stoneleaf.us> - 2016-07-01 09:00 -0700
Re: Namespaces are one honking great idea Steven D'Aprano <steve@pearwood.info> - 2016-07-02 03:10 +1000
Re: Namespaces are one honking great idea Ethan Furman <ethan@stoneleaf.us> - 2016-07-01 12:29 -0700
Re: Namespaces are one honking great idea Steven D'Aprano <steve@pearwood.info> - 2016-07-02 11:07 +1000
Re: Namespaces are one honking great idea Kevin Conway <kevinjacobconway@gmail.com> - 2016-07-02 01:50 +0000
Re: Namespaces are one honking great idea Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-07-01 19:55 -0700
Re: Namespaces are one honking great idea Steven D'Aprano <steve@pearwood.info> - 2016-07-03 13:22 +1000
Re: Namespaces are one honking great idea Random832 <random832@fastmail.com> - 2016-07-02 00:59 -0400
Re: Namespaces are one honking great idea Kevin Conway <kevinjacobconway@gmail.com> - 2016-07-02 15:34 +0000
Re: Namespaces are one honking great idea Steven D'Aprano <steve@pearwood.info> - 2016-07-03 13:44 +1000
Re: Namespaces are one honking great idea Ethan Furman <ethan@stoneleaf.us> - 2016-07-02 22:14 -0700
Re: Namespaces are one honking great idea Kevin Conway <kevinjacobconway@gmail.com> - 2016-07-03 22:02 +0000
Re: Namespaces are one honking great idea Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-07-03 16:21 -0700
Re: Namespaces are one honking great idea BartC <bc@freeuk.com> - 2016-07-04 01:19 +0100
Re: Namespaces are one honking great idea Ethan Furman <ethan@stoneleaf.us> - 2016-07-03 21:01 -0700
Re: Namespaces are one honking great idea Ethan Furman <ethan@stoneleaf.us> - 2016-07-02 16:28 -0700
Re: Namespaces are one honking great idea Chris Angelico <rosuav@gmail.com> - 2016-07-04 21:37 +1000
Re: Namespaces are one honking great idea Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-07-04 15:09 -0700
Re: Namespaces are one honking great idea Lawrence D’Oliveiro <lawrencedo99@gmail.com> - 2016-07-04 15:11 -0700
Re: Namespaces are one honking great idea jmp <jeanmichel@sequans.com> - 2016-07-04 17:58 +0200
Re: Namespaces are one honking great idea Chris Angelico <rosuav@gmail.com> - 2016-07-05 12:58 +1000
Re: Namespaces are one honking great idea Steven D'Aprano <steve@pearwood.info> - 2016-07-05 13:35 +1000
Re: Namespaces are one honking great idea Chris Angelico <rosuav@gmail.com> - 2016-07-05 13:47 +1000
Re: Namespaces are one honking great idea Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2016-07-05 16:09 +1000
A nestedmodule decorator (Re: Namespaces are one honking great idea) Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2016-07-05 21:10 +1200
Improved nestedmodule decorator implementation Gregory Ewing <greg.ewing@canterbury.ac.nz> - 2016-07-05 21:31 +1200
Re: Improved nestedmodule decorator implementation Steven D'Aprano <steve@pearwood.info> - 2016-07-05 20:54 +1000
Re: Namespaces are one honking great idea Steven D'Aprano <steve@pearwood.info> - 2016-07-05 12:34 +1000
Re: Namespaces are one honking great idea jmp <jeanmichel@sequans.com> - 2016-07-04 13:23 +0200
Re: Namespaces are one honking great idea carlosjosepita@gmail.com - 2016-07-09 07:05 -0700
Page 2 of 2 — ← Prev page 1 [2]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2016-07-03 21:01 -0700 |
| Message-ID | <mailman.57.1467605360.2295.python-list@python.org> |
| In reply to | #110971 |
On 07/03/2016 03:02 PM, Kevin Conway wrote: >At some point earlier Ethan Furman declared: >> It's not a language change. > > Perhaps. My argument is that anything that introduces a new class-like > construct and set of lexical scoping rules is a language change. For > example, if this change went into 2.7.13 would Jython suddenly be broken > because it hasn't implemented the new scoping rules? It's not a language change*. There is nothing for Jython, IronPython, Brython, etc., to implement. No scoping rule changes, nothing. The magic in Steven's name space is implemented by the metaclass by (presumably) rebuilding all the functions -- and that is how he manages the effective scoping rules. -- ~Ethan~ *Okay, it is not a language change the same way the addition of Enum was not a language change. On the other hand, asyncio did have some language changes (await, async, etc.).
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2016-07-02 16:28 -0700 |
| Message-ID | <mailman.31.1467502094.2295.python-list@python.org> |
| In reply to | #110924 |
On 07/02/2016 08:34 AM, Kevin Conway wrote: > For the proponents of namespace, what is deficient in the above example > that necessitates a language change? Adding a new widget is not changing the language. -- ~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-07-04 21:37 +1000 |
| Message-ID | <mailman.67.1467632250.2295.python-list@python.org> |
| In reply to | #110899 |
On Mon, Jul 4, 2016 at 9:23 PM, jmp <jeanmichel@sequans.com> wrote: > On 07/01/2016 04:13 PM, Steven D'Aprano wrote: >> >> But classes are not like the others: they must be instantiated before they >> can be used, and they are more than just a mere namespace grouping related >> entities. Classes support inheritance. Classes should be used for "is-a" >> relationships, not "has-a" relationships. Although classes (and instances) >> are namespaces, they provide fundamentally different kind of behaviour >> than >> modules and packages. > > > A namespace would not hurt but I really don't get why you don't consider > classes a valid and rather helpful namespace. > > 1/ classes do not have to be instantiated. > 2/ the fact that classes are more than a namespace is not an argument. > Almost any object in python is able to do more than what you are actually > using. > 3/ Classes are used as much as 'is-a' than 'has-a', class instances *have* a > state usually described by attributes > 4/ "Although classes (and instances) are namespaces, ". You seem to > contradict yourself. It was probably a rhetorical construct but it's rather > confusing. Functions within the namespace can't call other functions within the same namespace using unqualified names. This was a stated requirement. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <lawrencedo99@gmail.com> |
|---|---|
| Date | 2016-07-04 15:09 -0700 |
| Message-ID | <d06cc82d-c035-4a41-99ab-cb3e043f9e93@googlegroups.com> |
| In reply to | #111043 |
On Monday, July 4, 2016 at 11:37:44 PM UTC+12, Chris Angelico wrote: > Functions within the namespace can't call other functions within the > same namespace using unqualified names. This was a stated requirement. Doesn’t my @namespace decorator provide that?
[toc] | [prev] | [next] | [standalone]
| From | Lawrence D’Oliveiro <lawrencedo99@gmail.com> |
|---|---|
| Date | 2016-07-04 15:11 -0700 |
| Message-ID | <17c5d75a-f01d-467f-95f8-1e7228403722@googlegroups.com> |
| In reply to | #111050 |
On Tuesday, July 5, 2016 at 10:10:04 AM UTC+12, I wrote: > > On Monday, July 4, 2016 at 11:37:44 PM UTC+12, Chris Angelico wrote: > > > Functions within the namespace can't call other functions within the > > same namespace using unqualified names. This was a stated requirement. > > Doesn’t my @namespace decorator provide that? No it doesn’t.
[toc] | [prev] | [next] | [standalone]
| From | jmp <jeanmichel@sequans.com> |
|---|---|
| Date | 2016-07-04 17:58 +0200 |
| Message-ID | <mailman.71.1467647921.2295.python-list@python.org> |
| In reply to | #110899 |
On 07/04/2016 01:37 PM, Chris Angelico wrote:
> On Mon, Jul 4, 2016 at 9:23 PM, jmp <jeanmichel@sequans.com> wrote:
>> On 07/01/2016 04:13 PM, Steven D'Aprano wrote:
>>>
>>> But classes are not like the others: they must be instantiated before they
>>> can be used, and they are more than just a mere namespace grouping related
>>> entities. Classes support inheritance. Classes should be used for "is-a"
>>> relationships, not "has-a" relationships. Although classes (and instances)
>>> are namespaces, they provide fundamentally different kind of behaviour
>>> than
>>> modules and packages.
>>
>>
>> A namespace would not hurt but I really don't get why you don't consider
>> classes a valid and rather helpful namespace.
>>
>> 1/ classes do not have to be instantiated.
>> 2/ the fact that classes are more than a namespace is not an argument.
>> Almost any object in python is able to do more than what you are actually
>> using.
>> 3/ Classes are used as much as 'is-a' than 'has-a', class instances *have* a
>> state usually described by attributes
>> 4/ "Although classes (and instances) are namespaces, ". You seem to
>> contradict yourself. It was probably a rhetorical construct but it's rather
>> confusing.
>
> Functions within the namespace can't call other functions within the
> same namespace using unqualified names. This was a stated requirement.
>
> ChrisA
>
Ho, I missed that one.
But if it's the only missing requirement, wouldn't be like stating that
python instances are not instances because methods cannot call other
methods without "self."ed qualified name ? We like explicit qualified
stuff in python right ? ("explicit is better than implicit")
jm
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-07-05 12:58 +1000 |
| Message-ID | <mailman.81.1467687507.2295.python-list@python.org> |
| In reply to | #110899 |
On Tue, Jul 5, 2016 at 12:34 PM, Steven D'Aprano <steve@pearwood.info> wrote:
> *** IF *** you are willing to push the code out into its own separate .py
> file, you can use a module and write your code in a more natural form:
>
>
> # module example.py
> var = 999
>
> def spam(arg):
> return eggs(arg) + var
>
> def eggs(arg):
> return arg*2
>
>
> What I'm calling a "namespace" is just a module object that lives inside
> another module, without requiring a separate .py file. It only uses
> the "class" statement for pragmatic reasons: there's no other statement
> available that will do the job.
If you push your code into a separate .py file, you can reference the
original module by importing it. Is that also the normal way to use
"outer" functions etc from inside a namespace?
# demo.py
pi = 3.14
def stupidfib(x):
if x < 2: return x
return stupidfib(x-1) + stupidfib(x-2)
Namespace asdf: # (or class, however it's done)
def foo(x):
return stupidfib(x * pi) / pi
How should foo reference those "even more global" names? "from .
import pi, stupidfib" would work if you converted the module into a
package ("mv demo.py demo/__init__.py"), and "from demo import pi,
stupidfib" would work if you converted the namespace into a peer
module. Either could make sense.
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-07-05 13:35 +1000 |
| Message-ID | <577b2af3$0$1611$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #111074 |
On Tue, 5 Jul 2016 12:58 pm, Chris Angelico wrote: > On Tue, Jul 5, 2016 at 12:34 PM, Steven D'Aprano <steve@pearwood.info> > wrote: >> *** IF *** you are willing to push the code out into its own separate .py >> file, you can use a module and write your code in a more natural form: >> >> >> # module example.py >> var = 999 >> >> def spam(arg): >> return eggs(arg) + var >> >> def eggs(arg): >> return arg*2 >> >> >> What I'm calling a "namespace" is just a module object that lives inside >> another module, without requiring a separate .py file. It only uses >> the "class" statement for pragmatic reasons: there's no other statement >> available that will do the job. > > If you push your code into a separate .py file, you can reference the > original module by importing it. Is that also the normal way to use > "outer" functions etc from inside a namespace? Good question! With the current implementation, importing should work, but it's not necessary. The surrounding module (the real .py module) is inserted into the name resolution path of functions: py> x = 999 py> @namespace.Namespace ... class Test: ... def test(): ... print(x) ... py> Test.test() 999 Of course, the module-global x will be shadowed by any x in the Test namespace (which is the intent), and you cannot assign to them (also a feature). A bare `x = 1` inside the function will make x a local, unless you declare it global first, in which case it should assign to the Test namespace scope instead. -- Steven “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2016-07-05 13:47 +1000 |
| Message-ID | <mailman.82.1467690470.2295.python-list@python.org> |
| In reply to | #111091 |
On Tue, Jul 5, 2016 at 1:35 PM, Steven D'Aprano <steve@pearwood.info> wrote: >> If you push your code into a separate .py file, you can reference the >> original module by importing it. Is that also the normal way to use >> "outer" functions etc from inside a namespace? > > Good question! > > With the current implementation, importing should work, but it's not > necessary. The surrounding module (the real .py module) is inserted into > the name resolution path of functions: > > py> x = 999 > py> @namespace.Namespace > ... class Test: > ... def test(): > ... print(x) > ... > py> Test.test() > 999 Ah, fascinating. This does break the "just unindent and move to a new file if you want to break it out" equivalency, but it does make sense - it's a *nested* namespace, which modules (even in a package) are not. So you have the outer namespace acting pretty much the way builtins do. (Do nested namespaces work?) ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2016-07-05 16:09 +1000 |
| Message-ID | <577b4f06$0$2752$c3e8da3$76491128@news.astraweb.com> |
| In reply to | #111094 |
On Tuesday 05 July 2016 13:47, Chris Angelico wrote: > On Tue, Jul 5, 2016 at 1:35 PM, Steven D'Aprano <steve@pearwood.info> wrote: >>> If you push your code into a separate .py file, you can reference the >>> original module by importing it. Is that also the normal way to use >>> "outer" functions etc from inside a namespace? >> >> Good question! >> >> With the current implementation, importing should work, but it's not >> necessary. The surrounding module (the real .py module) is inserted into >> the name resolution path of functions: >> >> py> x = 999 >> py> @namespace.Namespace >> ... class Test: >> ... def test(): >> ... print(x) >> ... >> py> Test.test() >> 999 > > Ah, fascinating. This does break the "just unindent and move to a new > file if you want to break it out" equivalency, but it does make sense > - it's a *nested* namespace, which modules (even in a package) are > not. So you have the outer namespace acting pretty much the way > builtins do. (Do nested namespaces work?) I haven't got that far, but I expect that nested namespaces will be nested in name only, like nested functions in Python 1.5. There's only so far I can go without support from the compiler. If you nest a class inside another class, the inner class doesn't see variables in the outer class even during construction. So I'm pretty sure my namespace metaclass will inherit the same limitation. -- Steve
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2016-07-05 21:10 +1200 |
| Subject | A nestedmodule decorator (Re: Namespaces are one honking great idea) |
| Message-ID | <du1brpFe32qU1@mid.individual.net> |
| In reply to | #111103 |
Steven D'Aprano wrote:
> There's only so far I can go without support from the compiler.
It turns out one can go surprisingly far. Here's something I
cooked up that seems to meet almost all the requirements.
The only shortcoming I can think of is that a nestedmodule
inside another nestedmodule won't be able to see the names
in the outer nestedmodule directly (much like nested classes).
% python3 test_nestedmodule.py
0.7071067811865475
#------------------------------------------
#
# test_nestedmodule.py
#
#------------------------------------------
from math import pi, sin
from nestedmodule import nestedmodule
def f(x):
return x**2
@nestedmodule
def test():
def g(x):
return f(x) * pi
def h(x):
return sin(g(x))
y = test.h(0.5)
print(y)
#------------------------------------------
#
# nestedmodule.py
#
#------------------------------------------
from types import CodeType, ModuleType
def hack_code(f):
"""Hack 'return locals()' onto the end of the bytecode of f."""
code1 = f.__code__
bytes1 = code1.co_code
names1 = code1.co_names
n = len(names1)
names2 = names1 + ('locals',)
bytes2 = bytes1[:-4] + bytes([116, n, 0, 131, 0, 0, 83])
code2 = CodeType(code1.co_argcount, code1.co_kwonlyargcount, code1.co_nlocals,
code1.co_stacksize, code1.co_flags, bytes2, code1.co_consts, names2,
code1.co_varnames, code1.co_filename, code1.co_name, code1.co_firstlineno,
code1.co_lnotab, code1.co_freevars, code1.co_cellvars)
return code2
def nestedmodule(f):
c = hack_code(f)
l = eval(c, f.__globals__)
m = ModuleType(f.__name__)
m.__dict__.update(l)
return m
[toc] | [prev] | [next] | [standalone]
| From | Gregory Ewing <greg.ewing@canterbury.ac.nz> |
|---|---|
| Date | 2016-07-05 21:31 +1200 |
| Subject | Improved nestedmodule decorator implementation |
| Message-ID | <du1d4aFebp4U1@mid.individual.net> |
| In reply to | #111113 |
I wrote:
> The only shortcoming I can think of is that a nestedmodule
> inside another nestedmodule won't be able to see the names
> in the outer nestedmodule
Actually, that's not correct -- the version I posted before
actually crashes if you try to refer to a name in an outer
nestedmodule from an inner nestedmodule.
Here's an improved version that fully supports nesting to
any depth.
% python3 test_nested_nested.py
foo
blarg
#------------------------------------------
#
# test_nested_nested.py
#
#------------------------------------------
from nestedmodule import nestedmodule
@nestedmodule
def m1():
def foo():
print("foo")
@nestedmodule
def m2():
def blarg():
foo()
print("blarg")
m1.m2.blarg()
#------------------------------------------
#
# nestedmodule.py
#
#------------------------------------------
from types import CodeType, FunctionType, ModuleType
from dis import dis
def hack_code(f):
"""Hack 'return locals()' onto the end of the bytecode of f."""
code1 = f.__code__
bytes1 = code1.co_code
names1 = code1.co_names
n = len(names1)
names2 = names1 + ('locals',)
bytes2 = bytes1[:-4] + bytes([116, n, 0, 131, 0, 0, 83])
code2 = CodeType(code1.co_argcount, code1.co_kwonlyargcount, code1.co_nlocals,
code1.co_stacksize, code1.co_flags, bytes2, code1.co_consts, names2,
code1.co_varnames, code1.co_filename, code1.co_name, code1.co_firstlineno,
code1.co_lnotab, code1.co_freevars, code1.co_cellvars)
f2 = FunctionType(code2, f.__globals__, f.__name__, f.__kwdefaults__,
f.__closure__)
return f2
def nestedmodule(f):
f2 = hack_code(f)
l = f2()
m = ModuleType(f.__name__)
m.__dict__.update(l)
return m
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-07-05 20:54 +1000 |
| Subject | Re: Improved nestedmodule decorator implementation |
| Message-ID | <577b91ca$0$1620$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #111117 |
On Tue, 5 Jul 2016 07:31 pm, Gregory Ewing wrote: > I wrote: >> The only shortcoming I can think of is that a nestedmodule >> inside another nestedmodule won't be able to see the names >> in the outer nestedmodule > > Actually, that's not correct -- the version I posted before > actually crashes if you try to refer to a name in an outer > nestedmodule from an inner nestedmodule. > > Here's an improved version that fully supports nesting to > any depth. That's impressive. And scary. And I fear not portable, since it uses byte-code hacking. But still nicely done. -- Steven “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse.
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2016-07-05 12:34 +1000 |
| Message-ID | <577b1cc6$0$1584$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #110899 |
On Mon, 4 Jul 2016 09:23 pm, jmp wrote:
> On 07/01/2016 04:13 PM, Steven D'Aprano wrote:
>> But classes are not like the others: they must be instantiated before
>> they can be used, and they are more than just a mere namespace grouping
>> related entities. Classes support inheritance. Classes should be used for
>> "is-a" relationships, not "has-a" relationships. Although classes (and
>> instances) are namespaces, they provide fundamentally different kind of
>> behaviour than modules and packages.
>
> A namespace would not hurt but I really don't get why you don't consider
> classes a valid and rather helpful namespace.
I never said that.
This is where the term "namespace" can be ambiguous. "Namespace" can refer
to any of:
- an abstract mapping of symbols (names) to values;
- specific kinds of namespaces:
* the concrete C++/C#/PHP data type called "namespace";
* Python packages and modules;
* classes;
* instances of a class;
- the implementation (the __dict__ attribute of modules, classes);
etc. Now clearly a class is not the same thing as the class __dict__, and a
module is not the same as a class, and neither modules nor classes are the
same as a C++ namespace. Doesn't mean that classes aren't valid namespaces,
just that their semantics, use-cases and behaviour are different to those
of modules.
> 1/ classes do not have to be instantiated.
That's a bit of a sore point to me.
Some years ago I wrote here to ask what name is given to a class that is not
instantiated before being used. Singleton classes get instantiated once,
allowing a single instance. What if you had a class that didn't need
instantiating at all, so that the class itself was *effectively* the
singleton? What should that be called?
Instead of this:
class SingletonClass:
...
singleton = SingletonClass()
singleton.method()
what if we had this instead?
class singleton:
...
singleton.method()
I was roundly told that this was crazy talk, that the whole point of classes
was that they must be instantiated to use them, that code like the second
example would be confusing and very possibly bring about the fall of
Western Civilisation. The idea that this might be a legitimate alternative
to the singleton design pattern was dismissed.
(The Python community is terribly conservative when it comes to code.)
And, in a sense, they were right: there are two common ways to get
singleton-like behaviour in general, and in Python specifically:
- use class that allows only a single instance;
- use a module.
Using the class itself is unusual and surprising (especially to Java
programmers, where classes aren't even first-class values), and more so,
it's *inconvenient*.
To write a class which is used without instantiation, you should raise an
error on instantiation, decorate every method using classmethod or
staticmethod, and have methods have to call each other using the dotted
name:
class Example:
var = 999
def __init__(self):
raise TypeError('do not instantiate this class')
@classmethod
def spam(cls, arg):
return cls.eggs(arg) + cls.var
@classmethod
def eggs(cls, arg):
return arg*2
*** IF *** you are willing to push the code out into its own separate .py
file, you can use a module and write your code in a more natural form:
# module example.py
var = 999
def spam(arg):
return eggs(arg) + var
def eggs(arg):
return arg*2
What I'm calling a "namespace" is just a module object that lives inside
another module, without requiring a separate .py file. It only uses
the "class" statement for pragmatic reasons: there's no other statement
available that will do the job.
> 2/ the fact that classes are more than a namespace is not an argument.
> Almost any object in python is able to do more than what you are
> actually using.
There's one aspect of classes that is a deliberate design feature, but goes
against what I'm after: the fact that the class namespace itself is NOT
part of the method name resolution rules (except during class
construction). Try this:
x = 999
class Example:
x = 1
print(x) # called during class construction
@classmethod
def test(cls):
print(x)
Example.test()
This will print 1, then 999. We quite often get people complaining about
this. I'm not one of them. I want classes to keep the current rules. But it
shows that a class is not the right answer for a module-inside-a-module
object.
> 3/ Classes are used as much as 'is-a' than 'has-a', class instances
> *have* a state usually described by attributes
Instances have state, of course, but the relationship I'm talking about is
instance to class.
class Dog:
...
lassie = Dog()
Lassie is a dog, not "Lassie has a dog".
Lassie has a tail, not "Lassie is a tail".
That's why we have IS_instance and HAS_attr builtins.
The expectation is that a class represents a model of a physical kind of
thing, whether that's a Dog or a HTTPServer or a float. If you want a
collection of related functions, classes and variables, put them in a
different kind of namespace, namely a module (if using a separate .py file
is okay) or a Namespace.
--
Steven
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
[toc] | [prev] | [next] | [standalone]
| From | jmp <jeanmichel@sequans.com> |
|---|---|
| Date | 2016-07-04 13:23 +0200 |
| Message-ID | <mailman.65.1467631737.2295.python-list@python.org> |
| In reply to | #110899 |
On 07/01/2016 04:13 PM, Steven D'Aprano wrote: > But classes are not like the others: they must be instantiated before they > can be used, and they are more than just a mere namespace grouping related > entities. Classes support inheritance. Classes should be used for "is-a" > relationships, not "has-a" relationships. Although classes (and instances) > are namespaces, they provide fundamentally different kind of behaviour than > modules and packages. A namespace would not hurt but I really don't get why you don't consider classes a valid and rather helpful namespace. 1/ classes do not have to be instantiated. 2/ the fact that classes are more than a namespace is not an argument. Almost any object in python is able to do more than what you are actually using. 3/ Classes are used as much as 'is-a' than 'has-a', class instances *have* a state usually described by attributes 4/ "Although classes (and instances) are namespaces, ". You seem to contradict yourself. It was probably a rhetorical construct but it's rather confusing. jm
[toc] | [prev] | [next] | [standalone]
| From | carlosjosepita@gmail.com |
|---|---|
| Date | 2016-07-09 07:05 -0700 |
| Message-ID | <221b0501-eeb1-4c93-aa83-6c73854299c4@googlegroups.com> |
| In reply to | #110899 |
Hi all,
although it doesn't fit the bill 100%, I sometimes use this extremely simple function as a decorator:
def new(call):
return call()
For example:
@new
class MySingleton:
x = 2
y = 2
def sum(self, x, y):
return x + y
@new
def my_obj():
x = 2
y = 2
def sum(x, y):
return x + y
return Bundle(locals())
where Bundle is a simple subclass of dict implementing __xxxattr__ dunder methods.
Cheers
--
Carlos
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.python
csiph-web