On Sun, Nov 29, 2009 at 7:49 PM, Lie Ryan <lie.1...@gmail.com> wrote:
> On 11/29/2009 12:22 PM, The Music Guy wrote: > >> When I first started seeing @ show up in Python code, I said "what the >> heck is that? It looks so weird and _ugly_.I would never try to mess >> with that." But I started seeing it more and more, so I asked #python >> what it was. They told me about decorators, so I looked it up in the >> docs, and I thought the idea was interesting. It took me a while to >> figure out exactly how they worked--and judging from messages I've >> seen in #python a number of people have the same trouble understanding >> them. >> > > And we don't want a second flood of users asking about foo.$bar. > > > My point is that any particular syntax would look ugly to you only >> because you haven't seen it in use enough, and haven't used it enough >> yourself. >> > > You're absolutely right, and I have *never needed* to use the plain > getattr/setattr/delattr enough to even bother considering a syntax that > already looks ugly at first sight. For @decorators, everyone used it *often > enough* BEFORE it turned into a syntax that the ugly syntax is justified and > become "acceptable". If you can find a syntax that doesn't look ugly at > first sight +0, fine by me; otherwise -1, I don't want to be forced to read > an ugly syntax for a feature that I don't use often enough. It's not just > the syntax, the necessity+syntax don't add up well. > > > > But of course you haven't--it's not currently a valid > >> syntax. However, the ugliness would seem to go away after the syntax >> had been in use for a while. And again, the EXACT syntax of the >> feature can be adjusted until its "just right". >> > > In so far, your definition of adjusting only means something around > "[a-zA-Z0-9_]+\.[^a-zA-Z0-9_][<{(\[]?[a-zA-Z0-9_]+[>})\]]?" > that class of syntax is ugly; some are more acceptable (e.g. obj.[arg]) the > old thread have spawned better alternatives than that class of syntax. > > As for my specific use case, it's somewhat difficult to explain. >> > > You know that: > If the implementation is hard to explain it's a bad idea. > -- Zen of Python -- > > right? > > > > The > >> general idea was to isolate a pattern that I spotted repeated in >> several unrelated parts of my project. The pattern manifested itself >> as a set of 4-5 methods and/or properties on a class whose objects >> were designed to work in conjunction with other objects that fit a >> particular behavior. These other objects had methods and properties >> that were designed to interact with the first type of object in a >> similar but--how should I say--"inverted" fashion. >> > > Do you mean something like this? > > class A(object): > @property > def the_b(self): > return self._b > @the_b > def the_b(self, new_b): > self._b = new_b > self._b._a = self > > class B(object): > @property > def the_a(self): > return self._a > @the_a > def the_a(self, new_a): > self._a = new_a > self._a._b = self > > am I getting you right? If not, please elaborate and give an example of > what you actually meant. > > -- > http://mail.python.org/mailman/listinfo/python-list > I understand that in all likelyhood this feature won't be added to Python anytime soon, if at all. But I'd like to continue this discussion anyway; it's been enlightening for me. Even though I don't agree with the views of some of the people who've replied, I like the insight. And anyway, I think that if the syntax were already present, people would feel a lot more positively about it; it's the idea of adding it in so late in the game that people seem to have a problem with for the most part. It doesn't seem like anybody besides inhahe has actually realized that my proposition is actually different than PEP 363 in a subtle but crucial way. It's not _literally_ a shorthand for accessing the *attr functions; that's just the way I originally assumed it would be used most often. However, I have since realized that the syntax is more powerful than I originally thought: ANYWHERE that a name appeared--this includes function names, class names, function parameters, possibly even module names--could be replaced by an expression that would be evaluated to the name. That makes the use of any kind of brackets, except maybe <angle brackets>, bad options, as it would conflict with [lists,] {dicts,} (tuples,) or generic parenthesized (expressions). There must be a unique indicator of some kind, something that isn't already in use by the interpreter. That way there is no possible way that it could get confused with another syntactical construct. So you could do something like this: def class_factory(this, that) get_that = "get_"+that set_that = "set_"+that _that = "_" + that class $this (object): def __init__(self, $that = None): self.$_that = $that def $get_that (self): return self.$_that def $set_that (self, $that): self.$_that = $that $that = property($get_that, $set_that) return $this Compare the code above with this approximation that uses the current syntax rules: def class_factory(this, that): get_that_name = "get_"+that set_that_name = "set_"+that _that = "_" + that class This(object): def __init__(self, that = None): setattr(self, _that, that) This.__name__ = this def get_that(self, that): return getattr(self, _that) get_that.__name__ = get_that_name setattr(This, get_that_name, get_that.__get__(None, This)) def set_that(self, that): setattr(self, _that, that) set_that.__name__ = set_that_name setattr(This, set_that_name, set_that.__get__(None, This)) setattr(This, that, property(get_that, set_that)) return This Given either of the two class factories above, the following can be done: Spam = new_foo_class("Spam", "eggs") Eggs = new_foo_class("Eggs", "spam") myspam = Spam() myeggs = Eggs() myeggs.spam = myspam myspam.set_eggs( myeggs ) print myspam.get_eggs() # prints "<Eggs object at ...>" print myeggs._spam # prints "<Spam object at ...>" However, the following can only be done using the first example: myspam.set_eggs( eggs = myeggs ) For the second example, it would have to be this: myspam.set_eggs( that = myeggs ) The reason is that the parameter names for the first example are determined dynamically, which I don't think python allows you to do currently. The closest thing is **kwargs, but that's less readable than an actual parameter name. That was a relatively simple example; classes as simple as the ones generated by the It is more likely that the class generation could would appear in a metaclass's class constructor or decorator function, and there would be more than just the three attributes given.
-- http://mail.python.org/mailman/listinfo/python-list