Re: [Python-ideas] anonymous object support
2011/8/4 Matej Lieskovský <lieskovsky.matej@googlemail.com>:
Um, I'm kinda new round here but here goes: If I understood the problem, we are looking for a way of creating an object which has no specific class. My proposal: perhaps a "namespace" statement would do, behaving somewhat like this: namespace MyObject: statements is equivalent to: class MyClass(object): statements MyObject = MyClass() MyClass = None I chose "namespace" as that's what I think we are trying to create constructive criticism is welcome
Not useful enough to warrant the introduction of a new keyword, IMO. There's some overlap here with the proposed 'given' keyword, and as you noted yourself it can already be done with the class construct. You could use a metaclass/base class or a class decorator to disable instantiation, if you really feel like it. Also note that you can read attributes directly on a class. Finally, you'll want to use the 'del' keyword on your last line. This: del MyClass removes the reference to the class in the namespace, but doesn't actually delete the class itself (until garbage collection and when there's no remaining references - and MyObject is still "referencing" it here).
2011/8/5 dag.odenhall@gmail.com <dag.odenhall@gmail.com>
2011/8/4 Matej Lieskovský <lieskovsky.matej@googlemail.com>:
... perhaps a "namespace" statement would do, behaving somewhat like this: namespace MyObject: statements is equivalent to: class MyClass(object): statements MyObject = MyClass() MyClass = None ...
As a somewhat off-topic remark, this could already be accomplished with metaclasses. We could write def namespace(name, bases, d): return type(name, bases, d)() trivially then use it like class MyObject(metaclass=namespace): statements which is really quite slick conceptually. Syntactically, this is ugly and the terminology we use seems to confuse people. If Python was to introduce new syntax for this, it would ideally solve the broader problem here. Mike
On Aug 5, 2011, at 10:49 AM, Mike Graham wrote:
2011/8/5 dag.odenhall@gmail.com <dag.odenhall@gmail.com>
2011/8/4 Matej Lieskovský <lieskovsky.matej@googlemail.com>:
... perhaps a "namespace" statement would do, behaving somewhat like this: namespace MyObject: statements is equivalent to: class MyClass(object): statements MyObject = MyClass() MyClass = None ...
As a somewhat off-topic remark, this could already be accomplished with metaclasses.
I think a new keyword (possibly but not necessarily namespace) might good as a way of differentiating "real" classes from metaclass hacks. For example, some ORMs work using a "declarational" syntax with the class statement. That's fine… except that it looks like you can use the resulting objects like classes, when really there's a lot of meta-glue behind the scenes that means things will break if you try to use inheritance or other features of "real" classes. As another example, using metaclasses you can change namedtuple's syntax from the somewhat clunky Point = namedtuple('Point', 'x y') to the more elegant but confusing since it uses "class" class Point(NamedTuple): x y I sort of like this syntax, but I think it would crazy to use in production, because who besides the original creator of the hack would guess that class NamedTuple has a metaclass which uses the __prepare__ method to record the fields accessed during class creation? But with a namespace keyword you signal to the reader of the code: "Here be meta-dragons! Proceed with caution." The counterargument can be made, do we really want to encourage people to fiddle around with metaclasses any more than they already do? But my response to that is that people are already making ORMs and whatnot using the class keyword, so why not pave the cowpath? Also we could throw in some built in tools to make the metaclasses less confusing to work with. Also, hey free switch statement ;-) : key = random.choice(["case1", "case2"]) namespace dispatch(dict): def case1(): print("One") def case2(): print("Two") dispatch[key]() -- Carl
On Sat, Aug 6, 2011 at 12:37 AM, Carl Matthew Johnson <cmjohnson.mailinglist@gmail.com> wrote:
As another example, using metaclasses you can change namedtuple's syntax from the somewhat clunky
Point = namedtuple('Point', 'x y')
to the more elegant but confusing since it uses "class"
class Point(NamedTuple): x y
You don't even need to use __prepare__() if you make it look like this: @as_namedtuple class Point: x = ... y = ... Since Ellipsis became valid as a normal-use object this works. And that decorator is a snap to write. -eric
I sort of like this syntax, but I think it would crazy to use in production, because who besides the original creator of the hack would guess that class NamedTuple has a metaclass which uses the __prepare__ method to record the fields accessed during class creation? But with a namespace keyword you signal to the reader of the code: "Here be meta-dragons! Proceed with caution." The counterargument can be made, do we really want to encourage people to fiddle around with metaclasses any more than they already do? But my response to that is that people are already making ORMs and whatnot using the class keyword, so why not pave the cowpath? Also we could throw in some built in tools to make the metaclasses less confusing to work with.
Also, hey free switch statement ;-) :
key = random.choice(["case1", "case2"]) namespace dispatch(dict): def case1(): print("One") def case2(): print("Two")
dispatch[key]()
-- Carl _______________________________________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/mailman/listinfo/python-ideas
On 8/6/2011 2:53 AM, Eric Snow wrote:
On Sat, Aug 6, 2011 at 12:37 AM, Carl Matthew Johnson <cmjohnson.mailinglist@gmail.com> wrote:
As another example, using metaclasses you can change namedtuple's syntax from the somewhat clunky
Point = namedtuple('Point', 'x y')
to the more elegant but confusing since it uses "class"
class Point(NamedTuple): x y
If NamedTuple were documented as having a custom metaclass, and if this were a common idiom, that would not be too confusing as all.
You don't even need to use __prepare__() if you make it look like this:
@as_namedtuple class Point: x = ... y = ...
Since Ellipsis became valid as a normal-use object this works. And that decorator is a snap to write.
This looks ok to me too. New keywords and syntax should be *very* rare and reserved for things that cannot be done so easily with what we have now. -- Terry Jan Reedy
If NamedTuple were documented as having a custom metaclass, and if this were a common idiom, that would not be too confusing as all.
Or make the presence of a metaclass explicit, i.e. have NamedTuple be the metaclass. Working example in case anyone was curious how this is done: http://paste.pocoo.org/show/453814/ I think this might be acceptable in such edge cases as named tuples and enums, if the metaclass isn't hidden away in a base class. Might be difficult to explain to a beginner, but on the other hand they might find it easier to *read*.
My favorite declarative-namedtuple hack is http://code.activestate.com/recipes/500261-named-tuples/#c16 Devin On Sat, Aug 6, 2011 at 3:50 PM, Terry Reedy <tjreedy@udel.edu> wrote:
On 8/6/2011 2:53 AM, Eric Snow wrote:
On Sat, Aug 6, 2011 at 12:37 AM, Carl Matthew Johnson <cmjohnson.mailinglist@gmail.**com <cmjohnson.mailinglist@gmail.com>> wrote:
As another example, using metaclasses you can change namedtuple's syntax from the somewhat clunky
Point = namedtuple('Point', 'x y')
to the more elegant but confusing since it uses "class"
class Point(NamedTuple): x y
If NamedTuple were documented as having a custom metaclass, and if this were a common idiom, that would not be too confusing as all.
You don't even need to use __prepare__() if you make it look like this:
@as_namedtuple class Point: x = ... y = ...
Since Ellipsis became valid as a normal-use object this works. And that decorator is a snap to write.
This looks ok to me too. New keywords and syntax should be *very* rare and reserved for things that cannot be done so easily with what we have now.
-- Terry Jan Reedy
______________________________**_________________ Python-ideas mailing list Python-ideas@python.org http://mail.python.org/**mailman/listinfo/python-ideas<http://mail.python.org/mailman/listinfo/python-ideas>
On Aug 6, 2011, at 12:53 PM, Devin Jeanpierre wrote:
My favorite declarative-namedtuple hack is http://code.activestate.com/recipes/500261-named-tuples/#c16
Devin
For non-link followers: def _namedtuple(func): return namedtuple(func.__name__, func.__code__.co_varnames) @_namedtuple def Point(x,y): pass That is very clever, but it kind of illustrates my point about needing a new keyword. When you see "def" don't you naturally think, "OK, what comes out of this will be a function named Point." But what comes out of this is not a function. It's a namedtuple, which is quite different… A similar case can be made about @sort_list_with_keyfunc(my_list) def result(item): ... return normalized_item It's a neat way of getting out of writing the keyfunc before the sort, but it's a bad practice because you're def-ing a sorted list, not a function. Also a Ruby-like each can be done through abuse of decorators @each(my_list) def squared_list(item): return item ** 2 Neat but it breaks the reader's expectations. (Also, a list comprehension is shorter.)
2011/8/6 Carl Matthew Johnson <cmjohnson.mailinglist@gmail.com>:
On Aug 6, 2011, at 12:53 PM, Devin Jeanpierre wrote:
My favorite declarative-namedtuple hack is http://code.activestate.com/recipes/500261-named-tuples/#c16
Devin
For non-link followers:
def _namedtuple(func): return namedtuple(func.__name__, func.__code__.co_varnames)
@_namedtuple def Point(x,y): pass
That is very clever, but it kind of illustrates my point about needing a new keyword. When you see "def" don't you naturally think, "OK, what comes out of this will be a function named Point." But what comes out of this is not a function. It's a namedtuple, which is quite different…
I'm not sure I find that much of an objection. There are plenty of situations where decorators are used to seriously pervert the type of the defined name. Plus, what's a function? A class can be called as well. What's the difference?
A similar case can be made about
@sort_list_with_keyfunc(my_list) def result(item): ... return normalized_item
It's a neat way of getting out of writing the keyfunc before the sort, but it's a bad practice because you're def-ing a sorted list, not a function.
In this specific case I agree it's just confusing. (The difference is that 'Point' above still can be called with x and y arguments, returning a Point object.)
Also a Ruby-like each can be done through abuse of decorators
@each(my_list) def squared_list(item): return item ** 2
Neat but it breaks the reader's expectations. (Also, a list comprehension is shorter.)
Not to mention faster. The main reason why the argument against these doesn't provide an argument against @_namedtuple is that they don't create a callable thing at all. -- --Guido van Rossum (python.org/~guido)
On 8/7/2011 8:26 AM, Guido van Rossum wrote:
2011/8/6 Carl Matthew Johnson<cmjohnson.mailinglist-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>:
def _namedtuple(func): return namedtuple(func.__name__, func.__code__.co_varnames)
@_namedtuple def Point(x,y): pass
That is very clever, but it kind of illustrates my point about needing a new keyword. When you see "def" don't you naturally think, "OK, what comes out of this will be a function named Point." But what comes out of this is not a function. It's a namedtuple, which is quite different…
I'm not sure I find that much of an objection. There are plenty of situations where decorators are used to seriously pervert the type of the defined name. Plus, what's a function? A class can be called as well. What's the difference?
Calling the decorator NamedTuple might hint that the decorated result is the type of function we call a class. -- Terry Jan Reedy
participants (7)
-
Carl Matthew Johnson
-
dag.odenhall@gmail.com
-
Devin Jeanpierre
-
Eric Snow
-
Guido van Rossum
-
Mike Graham
-
Terry Reedy