Re: [Python-Dev] Adding any() and all()
And why not use the names already in use in numarray/Numeric ? They are called "sometrue" and "alltrue" ... IMHO, it explicits more what it means : alltrue(i<5 for i in l) sometrue(i<5 for i in l) Another point is: as I agree there is already a huge lot of builtins, shouldn't it be in some module ? Perhaps in itertools ? Pierre PS: It's my first post on the list, even if I'm reading it for a few months now ^_^ Peter Astrand a écrit : On Fri, 11 Mar 2005, Paul Moore wrote: Not sure this is pertinent but anyway: "any" and "all" are often used as variable names. "all" especially often and then almost always as a list of something. It would not be good to add "all" to the list of words to watch out for. Also, "all" is usually thought of as a list of Using "any" and "all" as variables hides the builtins, but doesn't disallow their use elsewhere. Personally, though, I wouldn't use "any" or "all" as variable names, so that's a style issue. Even though you can use them as variables (and shadow the builtins), you will still get warnings from "pychecker". The code will also be harder to read: When you see "all" in the middle of some code, you don't know if it's referring to the builtin or a variable. Personally, I think Python has too many builtins already. /Peter Åstrand <[EMAIL PROTECTED]> ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/pierre.barbier%40cirad.fr -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] hierarchicial named groups extension to the re library
[EMAIL PROTECTED] a écrit : Nicolas Fleury wrote: > [...] Actually, I ~would~ like to limit it to just named groups. I reckon, if you're not going to bother naming a group, then why would you have any interest in it. I guess its up for discussion how confusing this "new" way of thinking could be and what drawbacks it might have. I would find interesting to match every groups without naming them ! For example, if the position in the father group is the best meaning, why bother with names ? If you just allow the user to skip the compression stage it will do the trick ! That leads me to a question: would it be possible to use, as names for unnamed groups, integers instead of strings ? That way, you could access unnamed groups by their rank in their father group for example. A small example of what I would want: >>> buf="123 234 345, 123 256, and 123 289" >>> regex=r'^(( *\d+)+,)+ *(?P[^ ]+)(( *\d+)+).*$' >>> pat2=re2.compile(regex) >>> x=pat2.extract(buf) >>> x { 0: {'_value': "123 234 345,", 0: "123", 1: " 234", 2: " 345"}, 1: {'_value': " 123 256,", 0: " 123", 1:" 256"}, 'logic': {'_value': 'and'}, 3: {'_value': " 123 289", 1: " 123", 2:" 289"} } Pierre Regards. Chris. _______________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/pierre.barbier%40cirad.fr -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340 - possible new name for block-statement
Nick Coghlan a écrit : Python offers two variants on the basic iterative loop. "for NAME from EXPR:" enforces finalisation of the iterator. At loop completion, a well-behaved iterator is always completely exhausted. This form supports block management operations, that ensure timely release of resources such as locks or file handles. If the values being iterated over are not required, then the statement may be simplified to "for EXPR:". "for NAME in EXPR:" skips the finalisation step. At loop completion, a well-behaved iterator may still contain additional values. This form allows an iterator to be consumed in stages. Regardless of whether you like the above or not, I think the PEP's proposed use of 'as' is incorrect - it looks like the variable should be referring to the expression being iterated over, rather than the values returned from the iterator. Cheers, Nick. Well, I would go a step further and keep only the for-loop syntax, mainly because I don't understand why there is two syntax for things that's so close we can merge them ! You can simply states that the for-loop call the "__error__" method of the object if available without invalidating any other property of the new for-loop (ie. as defined in the PEP 340). One main reason is a common error could be (using the synchronised iterator introduced in the PEP): for l in synchronised(mylock): do_something() It will compile, run, never raise any error but the lock will be acquired and never released ! Then, I think there is no use case of a generator with __error__ in the for-loop as it is now. So, IMO, it is error-prone and useless to have two different syntaxes for such things. Pierre -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340 - possible new name for block-statement
Nick Coghlan a écrit : Pierre Barbier de Reuille wrote: One main reason is a common error could be (using the synchronised iterator introduced in the PEP): for l in synchronised(mylock): do_something() It will compile, run, never raise any error but the lock will be acquired and never released ! It's better than that. With the code above, CPython is actually likely to release the lock when the loop exits. Change the code to the below to ensure the lock doesn't get released: sync = synchronised(mylock): for l in sync: do_something() Well indeed, but this will be an implementation-dependant behaviour ... Then, I think there is no use case of a generator with __error__ in the for-loop as it is now. So, IMO, it is error-prone and useless to have two different syntaxes for such things. [...] The major danger I see is that you could then write a generator containing a yield inside a try/finally, _without_ applying the finalisation decorator. Leading to exactly the problem described above - the lock (or whatever) is never cleaned up, because the generator is not flagged for finalisation. In this scenario, even destruction of the generator object won't help. Mmmmh ... why introduce a new flag ? Can't you just test the presence of the "__error__" method ? This would lift your problem wouldn't it ? Cheers, Nick. P.S. I think PEP 340's proposed for loop semantics are currently incorrect, as BLOCK2 is unreachable. It should look more like the non-finalised semantics above (with BLOCK2 before the break in the except clause) -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340 -- loose ends
Nick Coghlan a écrit : >>3. I'm leaning against Phillip's proposal; IMO it adds more complexity >>for very little benefit. > > > See my response to Phillip. I think there could be an advantage to it if it > means that "for l in synchronized(lock)" raises an immediate error instead of > silently doing the wrong thing. First, I really think this PEP is needed for Python. But this is express exactly my main concern about it ! As far as I understand it, iterator-for-blocks and iterator-for-loops are two different beasts. Even if iterator-for-loops can be used within a block without damage, the use of iterator-for-block in a loop can lead to completely unpredictable result (and result really hard to find since they'll possibly involve race conditions or dead locks). To try being as clear as possible, I would say the iterator-for-loops are simplified iterator-for-blocks. IOW, if I were to put them in a class inheritance hierarchy (I don't say we should put them into one ;) ) iterator-for-block would be the base class of iterator-for-loop. Thus, as for-loops require an iterator-for-loop, they would raise an error if used with an iterator-for-block. But as blocks require an iterator-for-blocks they will allow iterator-for-loops too ! Cheers, Pierre -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340: Breaking out.
Tom Rothamel a écrit : > I have a question/suggestion about PEP 340. > > As I read the PEP right now, the code: > > > while True: > > block synchronized(v1): > if v1.field: > break > > time.sleep(1) > > > Will never break out of the enclosing while loop. This is because the > break breaks the while loop that the block statement is translated > into, instead of breaking the outer True statement. Well, that's exactly what it is intended to do and what I would expect it to do ! break/continue affect only the inner-most loop. > > Am I understanding this right, or am I misunderstanding this? > > If I am understanding this right, I would suggest allowing some way of > having the iterator call continue or break in the enclosing > context. (Perhaps by enclosing the entire translation of block in a > try-except construct, which catches Stop and Continue exceptions > raised by the generator and re-raises them in the outer context.) > > I hope this helps. > I don't want it like that ! This would differ with the break/continue used in other loops. If you need to break from many loops, enclose them into a function and return from it ! Pierre -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 340: Breaking out.
Skip Montanaro a écrit : > [...] > > Yeah, but "block synchronized(v1)" doesn't look like a loop. I think this > might be a common stumbling block for people using this construct. > > Skip > Well, this can be a problem, because indeed the black-statement introduce a new loop construct in Python. That's why I advocated some time ago against the introduction of a new name. IMHO, the for-loop syntax can be really used instead of blocks as its behavior if exactly the one of a for-loop if the iterator is an iterator-for-for and the current for-loop cannot be used with iterator-for-blocks. The main problem with this syntax is the use of the blocks for things that are not loops (like the synchronize object)! And they are, indeed, quite common ! (or they will be :) ). Pierre -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Proposal: defaultdict
Quoting [EMAIL PROTECTED]: > > Guido> Over lunch with Alex Martelli, he proposed that a subclass of > Guido> dict with this behavior (but implemented in C) would be a good > Guido> addition to the language. > > Instead, why not define setdefault() the way it should have been done in the > first place? When you create a dict it has the current behavior. If you > then call its setdefault() method that becomes the default value for missing > keys. > > d = {'a': 1}' > d['b'] # raises KeyError > d.get('c') # evaluates to None > d.setdefault(42) > d['b'] # evaluates to 42 > d.get('c') # evaluates to 42 > > For symmetry, setdefault() should probably be undoable: deldefault(), > removedefault(), nodefault(), default_free(), whatever. Well, first not ot break the current interface, and second because I think it reads better I would prefer : d = {'a': 1}' d['b'] # raises KeyError d.get('c') # evaluates to None d.default = 42 d['b'] # evaluates to 42 d.get('c') # evaluates to 42 And to undo the default, you can simply do : del d.default And of course, you can get the current value : d.default But then, as proposed many times, I would rather see a function call. Like : d.default = lambda key: 42 The argument of the function is the current key. It would allow things like that : d.default = time_comsuming_operation where time_comsuming_operation get a single argument. > > The only question in my mind is whether or not getting a non-existent value > under the influence of a given default value should stick that value in the > dictionary or not. > > down-with-more-builtins-ly, y'rs, > > Skip > ___ > Python-Dev mailing list > Python-Dev@python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > http://mail.python.org/mailman/options/python-dev/pierre.barbier%40cirad.fr > ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] partition() (was: Remove str.find in 3.0?)
Well, I want to come back on a point that wasn't discussed. I only found one positive comment here : http://mail.python.org/pipermail/python-dev/2005-August/055775.html It's about that : Raymond Hettinger wrote: > * The function always succeeds unless the separator argument is not a > string type or is an empty string. So, a typical call doesn't have to > be wrapped in a try-suite for normal usage. Well, I wonder if it's so good ! Almost all the use case I find would require something like: head, sep, tail = s.partition(t) if sep: do something else: do something else Like, if you want to extract the drive letter from a windows path : drive, sep, tail = path.partition(":") if not sep: drive = get_current_drive() # Because it's a local path Or, if I want to iterate over all the path parts in a UNIX path: sep = '/' while sep: head, sep, path = path.partition(sep) IMO, that read strange ... partitionning until sep is None :S Then, testing with "if" in Python is always a lot slower than having an exception launched from C extension inside a try...except block. So both construct would read like already a lot of Python code: try: head,sep,tail = s.partition(t) do something except SeparatorException: do something else and: sep='/' try: while 1: head, drop, path = path.partition(sep) except SeparatorException: The end To me, the try..except block to test end or error conditions are just part of Python design. So I don't understand why you don't want it ! For the separator, keeping it in the return values may be very useful, mainly because I would really like to use this function replacing string with a regexp (like a simplified version of the Qt method QStringList::split) and, in that case, the separator would be the actual matched separator string. Pierre -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] partition() (was: Remove str.find in 3.0?)
Josiah Carlson a écrit : > Pierre Barbier de Reuille <[EMAIL PROTECTED]> wrote: > >>Well, I want to come back on a point that wasn't discussed. I only found >>one positive comment here : >>http://mail.python.org/pipermail/python-dev/2005-August/055775.html > > > You apparently haven't been reading python-dev for around 36 hours, > because there have been over a dozen positive comments in regards to > str.partition(). Well, I wasn't criticizing the overall idea of str.partition, which I found very useful ! I'm just discussing one particular idea, which is to avoid the use of exceptions. > >>Raymond Hettinger wrote: >> >>>* The function always succeeds unless the separator argument is not a >>>string type or is an empty string. So, a typical call doesn't have to >>>be wrapped in a try-suite for normal usage. >> >>Well, I wonder if it's so good ! Almost all the use case I find would >>require something like: >> >>head, sep, tail = s.partition(t) >>if sep: >> do something >>else: >> do something else > > > Why don't you pause for a second and read Raymond's post here: > http://mail.python.org/pipermail/python-dev/2005-August/055781.html > > In that email there is a listing of standard library translations from > str.find to str.partition, and in every case, it is improved. If you > believe that str.index would be better used, take a moment and do a few > translations of the sections provided and compare them with the > str.partition examples. Well, what it does is exactly what I tought, you can express most of the use-cases of partition with: head, sep, tail = s.partition(sep) if not sep: #do something when it does not work else: #do something when it works And I propose to replace it by : try: head, sep, tail = s.partition(sep) # do something when it works except SeparatorError: # do something when it does not work What I'm talking about is consistency. In most cases in Python, or at least AFAIU, error testing is avoided and exception launching is preferred mainly for efficiency reasons. So my question remains: why prefer for that specific method returning an "error" value (i.e. an empty separator) against an exception ? Pierre -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] partition() (was: Remove str.find in 3.0?)
Eric Nieuwland a écrit : > I have some use cases with: > cut_at = some_str.find(sep) > head, tail = some_str[:cut_at], some_str[cut_at:] > and: > cut_at = some_str.find(sep) > head, tail = some_str[:cut_at], some_str[cut_at+offset:] # offset != > len(sep) > > So if partition() [or whatever it'll be called] could have an optional > second argument that defines the width of the 'cut' made, I would be > helped enormously. The default for this second argument would be > len(sep), to preserve the current proposal. Well, IMO, your example is much better written: import re rsep = re.compile(sep + '.'*offset) lst = re.split(resp, some_str, 1) head = lst[0] tail = lst[1] Or you want to have some "partition" method which accept regular expressions: head, sep, tail = some_str.partition(re.compile(sep+'.'*offset)) > > --eric > > ___ > Python-Dev mailing list > Python-Dev@python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > http://mail.python.org/mailman/options/python-dev/pierre.barbier%40cirad.fr > -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] partition() (was: Remove str.find in 3.0?)
Shane Hathaway a écrit : > Eric Nieuwland wrote: > >> Pierre Barbier de Reuille wrote: >> >>> Or you want to have some "partition" method which accept regular >>> expressions: >>> >>> head, sep, tail = some_str.partition(re.compile(sep+'.'*offset)) >> >> >> >> Neat! >> +1 on regexps as an argument to partition(). > > > Are you sure? I would instead expect to find a .partition method on a > regexp object: > > head, sep, tail = re.compile(sep+'.'*offset).partition(some_str) Well, to be consistent with current re module, it would be better to follow Antoine's suggestion : head, sep, tail = re.partition(re.compile(sep+'.'*offset), some_str) Pierre > > Shane > -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] partition() (was: Remove str.find in 3.0?)
Josiah Carlson a écrit : > Pierre Barbier de Reuille <[EMAIL PROTECTED]> wrote: > > 0.5 > > So, subtracting that .5 seconds from all the cases gives us... > > 0.343 seconds for .find's comparison > 0.313 seconds for .index's exception handling when an exception is not > raised > 3.797 seconds for .index's exception handling when an exception is > raised. Well, when I did benchmark that (two years ago) the difference was, AFAIR, much greater ! But well, I just have to adjust my internal data sets ;) Pierre > > In the case of a string being found, .index is about 10% faster than > .find . In the case of a string not being found, .index's exception > handlnig mechanics are over 11 times slower than .find's comparison. > > [...] > > - Josiah > -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] inplace operators and __setitem__
Phillip J. Eby a écrit : > At 03:12 PM 9/28/2005 +0200, Reinhold Birkenfeld wrote: [...] > Yes. See: > > http://www.python.org/2.0/new-python.html#SECTION00070 > > The purpose of the augmented assignment forms is to allow for the > possibility that the item's __i*__ method may or may not exist, and may or > may not return the same object. In the case where there is no __i*__ form, > or it does not return the same object, the lvalue *must* be re-bound to the > new value, or the semantics break. > > > >>A case where this matters is here: http://python.org/sf/1306777 > > > I've closed it as invalid; the behavior is as-defined. Rather than closing this as invalid, it would be wiser to update the documentation before ! Nothing corresponds to the current behavior. I think that in this page : http://docs.python.org/ref/augassign.html The last paragraph whould be replace by : """ For targets which are attribute (or indexed) references, the initial value is retrieved with a getattr() (resp. __getitem__) and the result is assigned with a setattr() (resp. __setitem__). Notice that the two methods do not necessarily refer to the same variable. When getattr() refers to a class variable, setattr() still writes to an instance variable. For example: """ That way it will be clearly defined in the documentation. Now, one can wonder if the augmented assignment is really an improvement. Lots of errors are made because they are counter-intuitive. For example, in the standard library, I found very few uses of "+=" with a mutable object, and none would be broken if "a += b" is to be replaced by "a = a+b". At worst, there will be a performance issue that will easily be fixed by using "extend" method for lists and corresponding methods for other objects. My opinion is, redefining the augmented assignment is a problem given the assignment semantic, and perhaps we should get rid of it. Pierre -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] inplace operators and __setitem__
Phillip J. Eby a écrit : > At 05:40 PM 9/28/2005 +0200, Pierre Barbier de Reuille wrote: > >> Rather than closing this as invalid, it would be wiser to update the >> documentation before ! Nothing corresponds to the current behavior. > > > I got my information from here: > > http://www.python.org/2.0/new-python.html#SECTION00070 I know ... I already read this page as you already posted it ;) > > >> I think that in this page : >> http://docs.python.org/ref/augassign.html >> >> The last paragraph whould be replace by : >> >> """ >> For targets which are attribute (or indexed) references, the initial >> value is retrieved with a getattr() (resp. __getitem__) and the result >> is assigned with a setattr() (resp. __setitem__). Notice that the two >> methods do not necessarily refer to the same variable. When getattr() >> refers to a class variable, setattr() still writes to an instance >> variable. For example: >> """ >> >> That way it will be clearly defined in the documentation. > > > Actually, the broken part is this sentence: > > """Also, when possible, the actual operation is performed in-place, > meaning that rather than creating a new object and assigning that to the > target, the old object is modified instead.""" > > It is subtly misleading, and would be better stated as: > > """Also, when possible, the actual operation is performed in-place, > meaning that rather than creating a new object the old object is > modified instead. In either case, however, the assignment to the target > is still performed.""" Indeed ! I missed that one :-S Your proposal should be integrated inside documentation (if anyone knows how to do so ...) !!! > >> Now, one can wonder if the augmented assignment is really an >> improvement. Lots of errors are made because they are counter-intuitive. > > > Huh? > Regularly, you see questions about augmented assignment on Python-tutor mailing list, I often have question in my lab because of problems ... most of the time people learn to avoid these operators in the end ! And my look in the standard library confirmed my intuition about it. > >> For example, in the standard library, I found very few uses of "+=" with >> a mutable object, and none would be broken if "a += b" is to be >> replaced by "a = a+b". At worst, there will be a performance issue that >> will easily be fixed by using "extend" method for lists and >> corresponding methods for other objects. > > > The intended use case (as I understand it) for augmented assignment is > to allow you to hint that an operation should be done in place *if* it > can be. It means that you are not expecting a new object to be the > result, but are prepared for the possibility it *might* be a new object. > > >> My opinion is, redefining the augmented assignment is a problem given >> the assignment semantic, and perhaps we should get rid of it. > > > How is it a problem? If the assignment semantic weren't what it is, > what would it be good for? You could just write an in-place method and > be done with it. The whole point is that it allows client code not to > care whether it's in-place or not, and to allow implementations to > decide (even at runtime) whether to return a different object or not. The problem is: this seems to be more a problem than a solution ! There is a huge difference between in-place or not, and I find it very difficult not to consider it. If you have a use-case for this "let the object decide about in-place operation or not" I'd be interested as I found none. Pierre PS: I'm not criticizing the assignment operator semantic which is exactly what is should be ;) -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] inplace operators and __setitem__
Ok, so I took a closer look at the documentation and tried a few things to understand better what you said and I have some remark ... Phillip J. Eby a ecrit : > At 06:15 PM 9/28/2005 +0200, Pierre Barbier de Reuille wrote: > >> Regularly, you see questions about augmented assignment on Python-tutor >> mailing list, I often have question in my lab because of problems ... >> most of the time people learn to avoid these operators in the end ! And >> my look in the standard library confirmed my intuition about it. > > > Some example of the problems would help. For the specific bug report > being discussed, I don't understand why someone would use augmented > assignment with an immutable lvalue, since x |= y is short for x = x | > y, which is clearly invalid on the face of it if x is a tuple member! Well, the problem is: >>> a = ([1,2], [3,4]) >>> a[0] += [5,6] ... a[0] *is* mutable, so the author of the bug report did not feel like its l-value was immutable as he supposed a[0] was the l-value, however in this case, both "a" and "a[0]" are l-values ! Otherwise, a very common problem (encounter regularly with labmates): >>> def foo(a,b): >>> a += b >>> return a >>> a = 3 >>> b = 4 >>> c = foo(a,b) # Works fine as intended >>> d = [1,2] >>> e = [3,4] >>> f = foo(d,e) # Oops ... *d* is modified Of course, actual code is much more complex, but the problem can be reduced to that most of the time. Also, on your sentence (which I find much more accurate than the current one): """Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object the old object is modified instead. In either case, however, the assignment to the target is still performed.""" I would add some pseudo-code equivalence like, if "__iadd__" is defined: a += b <=> a = a.__iadd__(b) which I believe is true from the look at the pseudo-code generated at compile-time. Like this, it is easier to remember and much less subject to interpretation than with human-language sentences ;) > >> The problem is: this seems to be more a problem than a solution ! >> There is a huge difference between in-place or not, and I find it very >> difficult not to consider it. > > > Consider string addition. The fact that string concatenation can be > implemented with += allows a string to consider based on its refcount to > return a new string or to modify itself in-place. If someone uses a = b > + c, it may be assumed that they still desire a reference to b, and that > therefore the operation *cannot* be done in-place. If they use a += b, > then this is a *hint* that an in-place operation is desirable. However, the implementation makes no use of the operator ! First, there is no "__iadd__" in the "str" class, second documentation says that "a+=b" and "a=a+b" are both optimized. So this does not validate for a use-case ^_^ > > So, there are two features of augmented assignment: > > 1. It is a shortcut for spelling out the full assignment > 2. Types that override augmented assignment methods may optimize > in-place operations, *without the need for client code to change*. Sure, I understood ... still I do not see any need for that, while I can see a bunch of problems ! >> If you have a use-case for this "let the >> object decide about in-place operation or not" I'd be interested as I >> found none. > > > The whole point of it is that I don't need to *care* whether a > particular use is such or not. I simply say what the code intends, and > then if somebody needs to pass in something different, or the behavior > of some other part of the system changes, then I get that for free. > Looking for a specific use case for that is like looking for a use case > for duck typing. That is, *everything* is a use case for it, because > the point isn't the initial state of the system. The point is what > happens when you *change* the system. My point here is: if the syntax causes a problem and does not solve any, why would we keep it ? As for duck-typing use cases are plenty ! A huge part of my code use benefit of duck-typing and so does the Python library, so there *are* use-cases ! Pierre -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] inplace operators and __setitem__
Done :) I summarized my point of view and I'm waiting for comments :) Pierre Aahz a écrit : > On Thu, Sep 29, 2005, Pierre Barbier de Reuille wrote: > >>Ok, so I took a closer look at the documentation and tried a few things >>to understand better what you said and I have some remark ... > > > I've got some counter-remarks, but python-dev is not the place to > discuss them. Please move this thread to comp.lang.python. -- Pierre Barbier de Reuille INRA - UMR Cirad/Inra/Cnrs/Univ.MontpellierII AMAP Botanique et Bio-informatique de l'Architecture des Plantes TA40/PSII, Boulevard de la Lironde 34398 MONTPELLIER CEDEX 5, France tel : (33) 4 67 61 65 77fax : (33) 4 67 61 56 68 ___ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com