Prev: Python daemonisation with python-daemon
Next: External Hashing [was Re: matching strings in a large set of strings]
From: Patrick Maupin on 1 May 2010 15:22 On May 1, 7:13 am, Tim Chase <t...(a)thechases.com> wrote: > On 05/01/2010 12:08 AM, Patrick Maupin wrote: > > > +=, -=, /=, *=, etc. conceptually (and, if lhs object supports in- > > place operator methods, actually) *modify* the lhs object. > > > Your proposed .= syntax conceptually *replaces* the lhs object > > (actually, rebinds the lhs symbol to the new object). > > The += family of operators really do rebind the symbol, not > modify the object. > > >>> from decimal import Decimal > >>> d = Decimal(42) > >>> e = Decimal(18) > >>> orig = d > >>> d += e > >>> d > Decimal("60") > >>> e > Decimal("18") > >>> orig > Decimal("42") > >>> d is orig > False > > If your suggestion that += *modifies* the object, then orig would > now unintuitively contain 60 and "d is orig" would return True. Well, I wrote "conceptually" (which I believe is true; it's certainly true for me) and "sometimes actually" (which I know is true): >>> x = [1,2,3,4,5] >>> y = x >>> x += [6] >>> y [1, 2, 3, 4, 5, 6] >>> >>> x = set() >>> y = x >>> x |= set([1]) >>> y set([1]) SO, if you find those results "unintuitive", perhaps you should upgrade your understanding of python. Personally, I don't find any of the results I gave, or the results you gave, surprising, so I'm not saying my "conceptually and sometimes actually modifies the result" is right for *you* but it works great for me. :-) > This doesn't preclude you from implementing a self-mutating += > style __add__ method and returning "self", but it's usually a bad > idea unless it's dire for performance (and even then, think it > over a couple times). Well, you should submit a bug report to fix the operation of lists and sets for a starter. But first, you might want to read PEP 203 -- augmented assignments. I particularly like the section which says: "The idea behind augmented assignment in Python is that it isn't just an easier way to write the common practice of storing the result of a binary operation in its left-hand operand, but also a way for the left- hand operand in question to know that it should operate `on itself', rather than creating a modified copy of itself." There are a lot of sections which have a similar flavor. If (which I doubt), the "augmented dot" is accepted, it won't necessarily have the same meaning. x = x.foo could replace x with any other kind of object, and I view it as a replacement, while I view x += foo as a modification. Regards, Pat
From: D'Arcy J.M. Cain on 1 May 2010 15:24 On Sun, 02 May 2010 05:08:53 +1000 Lie Ryan <lie.1296(a)gmail.com> wrote: > On 05/01/10 11:16, Steven D'Aprano wrote: > > On Fri, 30 Apr 2010 12:34:34 -0400, D'Arcy J.M. Cain wrote: > > > > In practice though, I think that's a difference that makes no difference. > > It walks like an operator, it swims like an operator, and it quacks like > > an operator. > > > > Nope it's not. A full-time operator in python have a reflected version Hi. Please watch the attributions. I didn't write that. I was the one who said that '.' was not an operator. -- D'Arcy J.M. Cain <darcy(a)druid.net> | Democracy is three wolves http://www.druid.net/darcy/ | and a sheep voting on +1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.
From: Steven D'Aprano on 1 May 2010 20:58 On Sun, 02 May 2010 05:08:53 +1000, Lie Ryan wrote: > On 05/01/10 11:16, Steven D'Aprano wrote: >> On Fri, 30 Apr 2010 12:34:34 -0400, D'Arcy J.M. Cain wrote: >> >> In practice though, I think that's a difference that makes no >> difference. It walks like an operator, it swims like an operator, and >> it quacks like an operator. >> >> > Nope it's not. A full-time operator in python have a reflected version > (e.g. __radd__), which dot does not have. What are the reflected versions of __eq__ and __ne__ (binary == and != operators)? And __neg__, __pos__ and __inv__ (for the unary - + and ~ operators)? And the three-argument form of __pow__ for power(1, 2, x)? > And Python's object system > makes it that the argument to __getattr__ is always a string even though > there might be a valid variable that corresponds to it: That is nothing to do with the object system, it is related to the semantics of Python syntax. a.b doesn't mean "apply the binary dot operator to arguments a and b". It is syntactic sugar for "look for an attribute named 'b' on object a". As such, the operands that __getattr__ receives are the object a and the *name* b (implemented as a string). Also, the implementation of attribute lookup is quite complex, with all sorts of special cases and optimizations. > a = MyClass() > b = MyClass() > print a . b > > I've often wanted to figure out a way to (ab)use python's dot operator > for function composition (i.e. f.g(x) ==> f(g(x)) ). There's no way to > do it, not without being way too hackish. That's a good example of where the difference does make a difference. -- Steven
From: Steven D'Aprano on 1 May 2010 21:32 On Sat, 01 May 2010 07:13:42 -0500, Tim Chase wrote: > On 05/01/2010 12:08 AM, Patrick Maupin wrote: >> +=, -=, /=, *=, etc. conceptually (and, if lhs object supports in- >> place operator methods, actually) *modify* the lhs object. >> >> Your proposed .= syntax conceptually *replaces* the lhs object >> (actually, rebinds the lhs symbol to the new object). > > The += family of operators really do rebind the symbol, not modify the > object. They potentially do both, depending on the object, even for built-ins. > >>> from decimal import Decimal [...] I'm not sure why you took the trouble to import Decimal for this example, when you could have shown the same thing with built-ins int or float. All three types are immutable. A counter example with a mutable type: >>> a = [] >>> b = a >>> a += [2] >>> a [2] >>> b [2] thus demonstrating that __iadd__ modifies in place as well as rebinds for at least one mutable type. > This doesn't preclude you from implementing a self-mutating += style > __add__ method and returning "self", but it's usually a bad idea Obviously the Python dev team don't agree with that :) Just to prove that += for lists is not an accident: >>> a = set() >>> b = a >>> a |= set([1]) >>> a set([1]) >>> b set([1]) -- Steven
From: Chris Rebert on 1 May 2010 22:03
On Sat, May 1, 2010 at 6:32 PM, Steven D'Aprano <steve(a)remove-this-cybersource.com.au> wrote: > On Sat, 01 May 2010 07:13:42 -0500, Tim Chase wrote: >> This doesn't preclude you from implementing a self-mutating += style >> __add__ method and returning "self", but it's usually a bad idea > > Obviously the Python dev team don't agree with that :) > > Just to prove that += for lists is not an accident: > >>>> a = set() >>>> b = a >>>> a |= set([1]) >>>> a > set([1]) >>>> b > set([1]) In both cases, __iOP__ operator methods are being used, not vanilla __OP__ methods, so neither of your examples are relevant to Mr. Chase's point. Cheers, Chris -- http://blog.rebertia.com |