<div dir="auto">Dear Steve, I'm sorry to annoy you by my proposal, but I do think using unicode might be wise in current stage. <div dir="auto"><br><div dir="auto">\triangleq could be print with unicode number \u225c, and adding plugins to support typing this in editors could be easy, just simply map \xxx to the specific unicode char when we press the tab after typing it. </div><div dir="auto"><br></div><div dir="auto">People using Julia language are proud of it but I think it's just something convenient could be used in any other language.</div><div dir="auto"><br></div><div dir="auto">There are other reasons to support unicode but it's out of this topic.</div><div dir="auto"><br></div><div dir="auto">Although ':=' and '->' are not perfect, in the range of ASCII it seems to be impossible to find a better one.</div></div></div><br><div class="gmail_quote"><div dir="ltr"> <<a href="mailto:python-ideas-request@python.org">python-ideas-request@python.org</a>> 于 2018年4月16日周一 上午12:53写道:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Send Python-ideas mailing list submissions to<br>
        <a href="mailto:python-ideas@python.org" target="_blank" rel="noreferrer">python-ideas@python.org</a><br>
<br>
To subscribe or unsubscribe via the World Wide Web, visit<br>
        <a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
or, via email, send a message with subject or body 'help' to<br>
        <a href="mailto:python-ideas-request@python.org" target="_blank" rel="noreferrer">python-ideas-request@python.org</a><br>
<br>
You can reach the person managing the list at<br>
        <a href="mailto:python-ideas-owner@python.org" target="_blank" rel="noreferrer">python-ideas-owner@python.org</a><br>
<br>
When replying, please edit your Subject line so it is more specific<br>
than "Re: Contents of Python-ideas digest..."<br>
Today's Topics:<br>
<br>
   1. Re: Rewriting file - pythonic way (Mahmoud Hashemi)<br>
   2. Re: Start argument for itertools.accumulate() [Was: Proposal:<br>
      A Reduce-Map Comprehension and a "last" builtin] (Tim Peters)<br>
   3. Re: Spelling of Assignment Expressions PEP 572 (was post #4)<br>
      (Steven D'Aprano)<br>
   4. Re: Rewriting file - pythonic way (Oleg Broytman)<br>
   5. Re: A cute Python implementation of itertools.tee (Tim Peters)<br>
<br><br><br>---------- Forwarded message ----------<br>From: Mahmoud Hashemi <<a href="mailto:mahmoud@hatnote.com" target="_blank" rel="noreferrer">mahmoud@hatnote.com</a>><br>To: python-ideas <<a href="mailto:python-ideas@python.org" target="_blank" rel="noreferrer">python-ideas@python.org</a>><br>Cc: <br>Bcc: <br>Date: Sun, 15 Apr 2018 09:10:57 -0700<br>Subject: Re: [Python-ideas] Rewriting file - pythonic way<br><div dir="ltr"><div><div><div>Depending on how firm your requirements around locking are, you may find this code useful: <a href="https://github.com/mahmoud/boltons/blob/6b0721b6aeda6d3ec6f5d31be7c741bc7fcc4635/boltons/fileutils.py#L303" target="_blank" rel="noreferrer">https://github.com/mahmoud/boltons/blob/6b0721b6aeda6d3ec6f5d31be7c741bc7fcc4635/boltons/fileutils.py#L303</a><br><br></div>(docs here: <a href="http://boltons.readthedocs.io/en/latest/fileutils.html#atomic-file-saving" target="_blank" rel="noreferrer">http://boltons.readthedocs.io/en/latest/fileutils.html#atomic-file-saving</a> )<br><br></div>Basically every operating system has _some_ way of doing an atomic file replacement, letting us guarantee that a file at a given location is always valid. atomic_save provides a unified interface to that cross-platform behavior.<br><br></div>The code does not do locking, as neither I nor its other users have wanted it, but I'd be happy to extend it if there's a sensible default.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Apr 15, 2018 at 8:19 AM, Oleg Broytman <span dir="ltr"><<a href="mailto:phd@phdru.name" target="_blank" rel="noreferrer">phd@phdru.name</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>On Sun, Apr 15, 2018 at 05:15:55PM +0300, Alexey Shrub <<a href="mailto:ashrub@yandex.ru" target="_blank" rel="noreferrer">ashrub@yandex.ru</a>> wrote:<br>
> В Воскресенье, 15 апр. 2018 в 2:40 , Nick Coghlan <<a href="mailto:ncoghlan@gmail.com" target="_blank" rel="noreferrer">ncoghlan@gmail.com</a>><br>
> написал:<br>
> > <a href="https://bugs.python.org/issue8604#msg174104" rel="noreferrer noreferrer" target="_blank">https://bugs.python.org/issue8604#msg174104</a> is the relevant tracker<br>
> > discussion<br>
> <br>
> Thanks all, I agree that universal and absolutly safe solution is very<br>
> difficult, but for experiment I made some draft<br>
> <a href="https://github.com/worldmind/scripts/tree/master/filerewrite" rel="noreferrer noreferrer" target="_blank">https://github.com/worldmind/scripts/tree/master/filerewrite</a><br>
<br>
</span>   Good!<br>
<span><br>
> main code here<br>
> <a href="https://github.com/worldmind/scripts/blob/master/filerewrite/filerewrite.py#L46" rel="noreferrer noreferrer" target="_blank">https://github.com/worldmind/scripts/blob/master/filerewrite/filerewrite.py#L46</a><br>
<br>
</span>   Can I recommend to catch exceptions in `backuper.backup()`,<br>
cleanup backuper and unlock locker?<br>
<span class="m_-6644462003908019400HOEnZb"><font color="#888888"><br>
Oleg.<br>
-- <br>
     Oleg Broytman            <a href="http://phdru.name/" rel="noreferrer noreferrer" target="_blank">http://phdru.name/</a>            <a href="mailto:phd@phdru.name" target="_blank" rel="noreferrer">phd@phdru.name</a><br>
           Programmers don't die, they just GOSUB without RETURN.<br>
</font></span><div class="m_-6644462003908019400HOEnZb"><div class="m_-6644462003908019400h5">_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank" rel="noreferrer">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
Code of Conduct: <a href="http://python.org/psf/codeofconduct/" rel="noreferrer noreferrer" target="_blank">http://python.org/psf/codeofconduct/</a><br>
</div></div></blockquote></div><br></div>
<br><br><br>---------- Forwarded message ----------<br>From: Tim Peters <<a href="mailto:tim.peters@gmail.com" target="_blank" rel="noreferrer">tim.peters@gmail.com</a>><br>To: Raymond Hettinger <<a href="mailto:raymond.hettinger@gmail.com" target="_blank" rel="noreferrer">raymond.hettinger@gmail.com</a>><br>Cc: Python-Ideas <<a href="mailto:python-ideas@python.org" target="_blank" rel="noreferrer">python-ideas@python.org</a>><br>Bcc: <br>Date: Sun, 15 Apr 2018 11:15:18 -0500<br>Subject: Re: [Python-ideas] Start argument for itertools.accumulate() [Was: Proposal: A Reduce-Map Comprehension and a "last" builtin]<br>[Raymond Hettinger <<a href="mailto:raymond.hettinger@gmail.com" target="_blank" rel="noreferrer">raymond.hettinger@gmail.com</a>>]<br>
> Q. Do other languages do it?<br>
> A. Numpy, no. R, no. APL, no. Mathematica, no. Haskell, yes.<br>
><br>
>     * <a href="http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.accumulate.html" rel="noreferrer noreferrer" target="_blank">http://docs.scipy.org/doc/numpy/reference/generated/numpy.ufunc.accumulate.html</a><br>
>     * <a href="https://stat.ethz.ch/R-manual/R-devel/library/base/html/cumsum.html" rel="noreferrer noreferrer" target="_blank">https://stat.ethz.ch/R-manual/R-devel/library/base/html/cumsum.html</a><br>
>     * <a href="http://microapl.com/apl/apl_concepts_chapter5.html" rel="noreferrer noreferrer" target="_blank">http://microapl.com/apl/apl_concepts_chapter5.html</a><br>
>       \+ 1 2 3 4 5<br>
>       1 3 6 10 15<br>
>     * <a href="https://reference.wolfram.com/language/ref/Accumulate.html" rel="noreferrer noreferrer" target="_blank">https://reference.wolfram.com/language/ref/Accumulate.html</a><br>
>     * <a href="https://www.haskell.org/hoogle/?hoogle=mapAccumL" rel="noreferrer noreferrer" target="_blank">https://www.haskell.org/hoogle/?hoogle=mapAccumL</a><br>
<br>
There's also C++, which is pretty much "yes" to every variation<br>
discussed so far:<br>
<br>
* partial_sum() is like Python's current accumulate(), including<br>
defaulting to doing addition.<br>
<br>
<a href="http://en.cppreference.com/w/cpp/algorithm/partial_sum" rel="noreferrer noreferrer" target="_blank">http://en.cppreference.com/w/cpp/algorithm/partial_sum</a><br>
<br>
* inclusive_scan() is also like accumulate(), but allows an optional<br>
"init" argument (which is returned if specified), and there's no<br>
guarantee of "left-to-right" evaluation (it's intended for associative<br>
binary functions, and wants to allow parallelism in the<br>
implementation).<br>
<br>
<a href="http://en.cppreference.com/w/cpp/algorithm/inclusive_scan" rel="noreferrer noreferrer" target="_blank">http://en.cppreference.com/w/cpp/algorithm/inclusive_scan</a><br>
<br>
* exclusive_scan() is like inclusive_scan(), but _requires_ an "init"<br>
argument (which is not returned).<br>
<br>
<a href="http://en.cppreference.com/w/cpp/algorithm/exclusive_scan" rel="noreferrer noreferrer" target="_blank">http://en.cppreference.com/w/cpp/algorithm/exclusive_scan</a><br>
<br>
* accumulate() is like Python's functools.reduce(), but the operation<br>
is optional and defaults to addition, and an "init" argument is<br>
required.<br>
<br>
<a href="http://en.cppreference.com/w/cpp/algorithm/accumulate" rel="noreferrer noreferrer" target="_blank">http://en.cppreference.com/w/cpp/algorithm/accumulate</a><br>
<br>
<br><br><br>---------- Forwarded message ----------<br>From: "Steven D'Aprano" <<a href="mailto:steve@pearwood.info" target="_blank" rel="noreferrer">steve@pearwood.info</a>><br>To: <a href="mailto:python-ideas@python.org" target="_blank" rel="noreferrer">python-ideas@python.org</a><br>Cc: <br>Bcc: <br>Date: Mon, 16 Apr 2018 02:15:59 +1000<br>Subject: Re: [Python-ideas] Spelling of Assignment Expressions PEP 572 (was post #4)<br>On Sun, Apr 15, 2018 at 11:11:37PM +0800, Thautwarm Zhao wrote:<br>
<br>
> I think maybe we can use unicode characters like ≜ (\triangleq) and add the<br>
> support of unicode completion to python repl. The unicode completion of<br>
> editors or ides has been quite mature.<br>
<br>
What key combination do I need to type to get ≜ in the following editors <br>
please? I tried typing \triangleq but all I got was \triangleq.<br>
<br>
Notepad (Windows)<br>
Brackets (Mac)<br>
BBEdit (Mac)<br>
kwrite (Linux)<br>
kate<br>
nano<br>
geany<br>
gedit<br>
<br>
as well as IDLE, my mail client (kmail, Thunderbird or mutt), my web <br>
browsers (Firefox, Opera and Chromium), the interactive interpreter in <br>
various different consoles, my Usenet client (Pan and KNode) and IRC <br>
(pidgin).<br>
<br>
Oh, having it work in LibreOffice and GoogleApps too would be nice, <br>
although not essential since I don't often write code in them.<br>
<br>
And what decent fonts do I need to install for ≜ to show up as something <br>
other than a square box ("missing glyph")?<br>
<br>
<br>
-- <br>
Steve<br>
<br>
<br><br><br>---------- Forwarded message ----------<br>From: Oleg Broytman <<a href="mailto:phd@phdru.name" target="_blank" rel="noreferrer">phd@phdru.name</a>><br>To: <a href="mailto:python-ideas@python.org" target="_blank" rel="noreferrer">python-ideas@python.org</a><br>Cc: <br>Bcc: <br>Date: Sun, 15 Apr 2018 18:49:16 +0200<br>Subject: Re: [Python-ideas] Rewriting file - pythonic way<br>On Sun, Apr 15, 2018 at 09:10:57AM -0700, Mahmoud Hashemi <<a href="mailto:mahmoud@hatnote.com" target="_blank" rel="noreferrer">mahmoud@hatnote.com</a>> wrote:<br>
> Depending on how firm your requirements around locking are, you may find<br>
> this code useful:<br>
> <a href="https://github.com/mahmoud/boltons/blob/6b0721b6aeda6d3ec6f5d31be7c741bc7fcc4635/boltons/fileutils.py#L303" rel="noreferrer noreferrer" target="_blank">https://github.com/mahmoud/boltons/blob/6b0721b6aeda6d3ec6f5d31be7c741bc7fcc4635/boltons/fileutils.py#L303</a><br>
> <br>
> (docs here:<br>
> <a href="http://boltons.readthedocs.io/en/latest/fileutils.html#atomic-file-saving" rel="noreferrer noreferrer" target="_blank">http://boltons.readthedocs.io/en/latest/fileutils.html#atomic-file-saving</a> )<br>
> <br>
> Basically every operating system has _some_ way of doing an atomic file<br>
> replacement, letting us guarantee that a file at a given location is always<br>
> valid. atomic_save provides a unified interface to that cross-platform<br>
> behavior.<br>
> <br>
> The code does not do locking, as neither I nor its other users have wanted<br>
> it, but I'd be happy to extend it if there's a sensible default.<br>
<br>
   I don't like it renames the file at the end. Renaming could lead to<br>
changed file ownership and permissions; restoring permissions is not<br>
always possible, restoring ownership is almost never possible. Renaming<br>
is also not always possible due to restricted directory permissions.<br>
<br>
> On Sun, Apr 15, 2018 at 8:19 AM, Oleg Broytman <<a href="mailto:phd@phdru.name" target="_blank" rel="noreferrer">phd@phdru.name</a>> wrote:<br>
> <br>
> > On Sun, Apr 15, 2018 at 05:15:55PM +0300, Alexey Shrub <<a href="mailto:ashrub@yandex.ru" target="_blank" rel="noreferrer">ashrub@yandex.ru</a>><br>
> > wrote:<br>
> > > В Воскресенье, 15 апр. 2018 в 2:40 , Nick Coghlan <<a href="mailto:ncoghlan@gmail.com" target="_blank" rel="noreferrer">ncoghlan@gmail.com</a>><br>
> > > написал:<br>
> > > > <a href="https://bugs.python.org/issue8604#msg174104" rel="noreferrer noreferrer" target="_blank">https://bugs.python.org/issue8604#msg174104</a> is the relevant tracker<br>
> > > > discussion<br>
> > ><br>
> > > Thanks all, I agree that universal and absolutly safe solution is very<br>
> > > difficult, but for experiment I made some draft<br>
> > > <a href="https://github.com/worldmind/scripts/tree/master/filerewrite" rel="noreferrer noreferrer" target="_blank">https://github.com/worldmind/scripts/tree/master/filerewrite</a><br>
> ><br>
> >    Good!<br>
> ><br>
> > > main code here<br>
> > > <a href="https://github.com/worldmind/scripts/blob/master/" rel="noreferrer noreferrer" target="_blank">https://github.com/worldmind/scripts/blob/master/</a><br>
> > filerewrite/filerewrite.py#L46<br>
> ><br>
> >    Can I recommend to catch exceptions in `backuper.backup()`,<br>
> > cleanup backuper and unlock locker?<br>
<br>
<br>
Oleg.<br>
-- <br>
     Oleg Broytman            <a href="http://phdru.name/" rel="noreferrer noreferrer" target="_blank">http://phdru.name/</a>            <a href="mailto:phd@phdru.name" target="_blank" rel="noreferrer">phd@phdru.name</a><br>
           Programmers don't die, they just GOSUB without RETURN.<br>
<br>
<br><br><br>---------- Forwarded message ----------<br>From: Tim Peters <<a href="mailto:tim.peters@gmail.com" target="_blank" rel="noreferrer">tim.peters@gmail.com</a>><br>To: Antoine Pitrou <<a href="mailto:solipsis@pitrou.net" target="_blank" rel="noreferrer">solipsis@pitrou.net</a>><br>Cc: Python-Ideas <<a href="mailto:python-ideas@python.org" target="_blank" rel="noreferrer">python-ideas@python.org</a>><br>Bcc: <br>Date: Sun, 15 Apr 2018 11:52:49 -0500<br>Subject: Re: [Python-ideas] A cute Python implementation of itertools.tee<br>[Antoine Pitrou <<a href="mailto:solipsis@pitrou.net" target="_blank" rel="noreferrer">solipsis@pitrou.net</a>>]<br>
> This implementation doesn't work with Python 3.7 or 3.8.<br>
> I've tried it here:<br>
> <a href="https://gist.github.com/pitrou/b3991f638300edb6d06b5be23a4c66d6" rel="noreferrer noreferrer" target="_blank">https://gist.github.com/pitrou/b3991f638300edb6d06b5be23a4c66d6</a><br>
><br>
> and get:<br>
> Traceback (most recent call last):<br>
>   File "mytee.py", line 14, in gen<br>
>     mylast = last[1] = last = [next(it), None]<br>
> StopIteration<br>
><br>
> The above exception was the direct cause of the following exception:<br>
><br>
> Traceback (most recent call last):<br>
>   File "mytee.py", line 47, in <module><br>
>     run(mytee1)<br>
>   File "mytee.py", line 36, in run<br>
>     lists[i].append(next(iters[i]))<br>
> RuntimeError: generator raised StopIteration<br>
><br>
> (Yuck!)<br>
<br>
Thanks for trying!  I wonder whether that will break other code.  I<br>
wrote PEP 255, and this part was intentional at the time:<br>
<br>
"""<br>
If an unhandled exception-- including, but not limited to,<br>
StopIteration --is raised by, OR PASSES THROUGH [emphasis added], a<br>
generator function, then the exception is passed on to the caller in<br>
the usual way, and subsequent attempts to resume the generator<br>
function raise StopIteration.<br>
"""<br>
<br>
I've exploited that a number of times.<br>
<br>
<br>
> In short, you want the following instead:<br>
><br>
>                 try:<br>
>                     mylast = last[1] = last = [next(it), None]<br>
>                 except StopIteration:<br>
>                     return<br>
<br>
No, I don't ;-)  If I have to catch StopIteration myself now, then I<br>
want the entire "white True:" loop in the "try" block.  Setting up<br>
try/except machinery anew on each iteration would add significant<br>
overhead; doing it just once per derived generator wouldn't.<br>
<br>
<br>
>>     def mytee(xs, n):<br>
>>         last = [None, None]<br>
>><br>
>>         def gen(it, mylast):<br>
>>             nonlocal last<br>
>>             while True:<br>
>>                 mylast = mylast[1]<br>
>>                 if not mylast:<br>
>>                     mylast = last[1] = last = [next(it), None]<br>
<br>
> That's smart and obscure :-o<br>
> The way it works is that the `last` assignment changes the `last` value<br>
> seen by all derived generators, while the `last[1]` assignment updates<br>
> the bindings made in the other generators' `mylast` lists...  It's<br>
> difficult to find the words to explain it.<br>
<br>
Which is why I didn't even try - I did warn people that if they<br>
thought it "was obvious", they hadn't yet thought hard enough ;-)<br>
Good job!<br>
<br>
<br>
> The chained assignment makes it more difficult to parse as well (when I<br>
> read this I don't know if `last[i]` or `last` gets assigned first;<br>
> apparently the answer is `last[i]`, otherwise the recipe wouldn't work<br>
> correctly).<br>
<br>
Ya, I had to look it up too :-)  Although, like almost everything else<br>
in Python, chained assignments proceed "left to right".  I was just<br>
trying to make it as short as possible, to increase the "huh - can<br>
something that tiny really work?!" healthy skepticism factor :-)<br>
<br>
<br>
>  Perhaps like this:<br>
><br>
>         while True:<br>
>             mylast = mylast[1]<br>
>             if not mylast:<br>
>                 try:<br>
>                     # Create new list link<br>
>                     mylast = [next(it), None]<br>
>                 except StopIteration:<br>
>                     return<br>
>                 else:<br>
>                     # Append to other generators `mylast` linked lists<br>
>                     last[1] = mylast<br>
>                     # Update shared list link<br>
>                     last = last[1]<br>
>             yield mylast[0]<br>
<br>
I certainly agree that's easier to follow.  But that wasn't really the point ;-)<br>
<br>
_______________________________________________<br>
Python-ideas mailing list<br>
<a href="mailto:Python-ideas@python.org" target="_blank" rel="noreferrer">Python-ideas@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-ideas" rel="noreferrer noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-ideas</a><br>
</blockquote></div>