Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #67520 > unrolled thread
| Started by | "ast" <nomail@invalid.com> |
|---|---|
| First post | 2014-03-03 10:42 +0100 |
| Last post | 2014-03-05 09:01 +1100 |
| Articles | 13 on this page of 93 — 21 participants |
Back to article view | Back to comp.lang.python
Reference "ast" <nomail@invalid.com> - 2014-03-03 10:42 +0100
Object identity (was: Reference) Ben Finney <ben+python@benfinney.id.au> - 2014-03-03 21:00 +1100
Re: Object identity (was: Reference) "ast" <nomail@invalid.com> - 2014-03-03 11:21 +0100
Re: Reference "Mark H. Harris" <harrismh777@gmail.com> - 2014-03-03 05:09 -0800
Re: Reference Grant Edwards <invalid@invalid.invalid> - 2014-03-03 14:29 +0000
Re: Reference Rustom Mody <rustompmody@gmail.com> - 2014-03-03 07:52 -0800
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-04 08:10 +1100
Re: Reference Tim Chase <python.list@tim.thechases.com> - 2014-03-03 15:24 -0600
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-04 08:31 +1100
Re: Reference Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-03 21:35 +0000
Re: Reference Marko Rauhamaa <marko@pacujo.net> - 2014-03-04 00:07 +0200
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-04 09:18 +1100
Re: Reference Alister <alister.ware@ntlworld.com> - 2014-03-04 11:10 +0000
Re: Reference Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-04 11:48 +0000
Re: Reference "Rhodri James" <rhodri@wildebst.org.uk> - 2014-03-05 00:25 +0000
Re: Reference Tim Chase <python.list@tim.thechases.com> - 2014-03-03 15:51 -0600
Re: Reference Jerry Hill <malaclypse2@gmail.com> - 2014-03-03 17:02 -0500
Re: Reference Marko Rauhamaa <marko@pacujo.net> - 2014-03-04 00:22 +0200
Re: Reference Chris Angelico <rosuav@gmail.com> - 2014-03-04 09:27 +1100
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-04 09:33 +1100
Re: Reference Steven D'Aprano <steve@pearwood.info> - 2014-03-04 04:52 +0000
Re: Reference Chris Angelico <rosuav@gmail.com> - 2014-03-04 16:24 +1100
Re: Reference "Rhodri James" <rhodri@wildebst.org.uk> - 2014-03-05 01:08 +0000
Re: Reference Roy Smith <roy@panix.com> - 2014-03-04 21:09 -0500
Re: Reference Rustom Mody <rustompmody@gmail.com> - 2014-03-04 19:36 -0800
Re: Reference Ian Kelly <ian.g.kelly@gmail.com> - 2014-03-04 21:08 -0700
Re: Reference Rustom Mody <rustompmody@gmail.com> - 2014-03-04 20:31 -0800
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-05 15:32 +1100
Re: Reference Rustom Mody <rustompmody@gmail.com> - 2014-03-04 20:47 -0800
Re: Reference Steven D'Aprano <steve@pearwood.info> - 2014-03-05 05:06 +0000
Re: Reference Rustom Mody <rustompmody@gmail.com> - 2014-03-04 21:47 -0800
Re: Reference alex23 <wuwei23@gmail.com> - 2014-03-05 16:01 +1000
Re: Reference Rustom Mody <rustompmody@gmail.com> - 2014-03-04 22:10 -0800
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-05 17:22 +1100
Re: Reference alex23 <wuwei23@gmail.com> - 2014-03-05 16:28 +1000
Re: Reference Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-05 12:24 +0000
Re: Reference Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-05 12:21 +0000
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-05 17:20 +1100
Re: Reference Rustom Mody <rustompmody@gmail.com> - 2014-03-05 09:40 -0800
Re: Reference Tim Chase <python.list@tim.thechases.com> - 2014-03-05 12:12 -0600
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-06 05:33 +1100
Re: Reference Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-05 18:19 +0000
Re: Reference Marko Rauhamaa <marko@pacujo.net> - 2014-03-05 22:23 +0200
Re: Reference Grant Edwards <invalid@invalid.invalid> - 2014-03-05 20:31 +0000
Re: Reference Marko Rauhamaa <marko@pacujo.net> - 2014-03-05 22:46 +0200
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-06 08:07 +1100
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-06 08:10 +1100
Re: Reference Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-05 21:34 +0000
Re: Reference Terry Reedy <tjreedy@udel.edu> - 2014-03-05 18:00 -0500
Re: Reference Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-06 03:01 +0000
Re: Reference Rustom Mody <rustompmody@gmail.com> - 2014-03-04 22:03 -0800
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-05 17:26 +1100
Re: Reference Chris Angelico <rosuav@gmail.com> - 2014-03-05 17:32 +1100
Re: Reference Tim Chase <python.list@tim.thechases.com> - 2014-03-05 08:24 -0600
Re: Reference Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-05 18:29 +0000
Re: Reference Marko Rauhamaa <marko@pacujo.net> - 2014-03-05 22:34 +0200
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-06 08:01 +1100
Re: Reference Marko Rauhamaa <marko@pacujo.net> - 2014-03-05 23:14 +0200
Re: Reference Chris Angelico <rosuav@gmail.com> - 2014-03-06 08:26 +1100
Re: Reference Marko Rauhamaa <marko@pacujo.net> - 2014-03-05 23:50 +0200
Re: Reference Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-06 00:35 +0000
Re: Reference Chris Angelico <rosuav@gmail.com> - 2014-03-06 11:50 +1100
Re: Reference Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-06 17:46 +0000
Re: Reference Tim Chase <python.list@tim.thechases.com> - 2014-03-05 15:33 -0600
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-06 08:37 +1100
Re: Reference Marko Rauhamaa <marko@pacujo.net> - 2014-03-06 02:52 +0200
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-06 12:05 +1100
Re: Reference alex23 <wuwei23@gmail.com> - 2014-03-06 12:12 +1000
Re: Reference Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-05 21:46 +0000
Re: Reference Marko Rauhamaa <marko@pacujo.net> - 2014-03-05 08:23 +0200
Re: Reference Rustom Mody <rustompmody@gmail.com> - 2014-03-04 22:33 -0800
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-05 17:40 +1100
Re: Reference Mark Lawrence <breamoreboy@yahoo.co.uk> - 2014-03-05 12:35 +0000
Re: Reference Chris Angelico <rosuav@gmail.com> - 2014-03-05 23:45 +1100
Re: Reference Jerry Hill <malaclypse2@gmail.com> - 2014-03-04 10:19 -0500
Re: Reference Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-03-04 15:42 +0000
Re: Reference Chris Angelico <rosuav@gmail.com> - 2014-03-05 03:02 +1100
Re: Reference Roy Smith <roy@panix.com> - 2014-03-04 11:14 -0500
Re: Reference MRAB <python@mrabarnett.plus.com> - 2014-03-04 17:12 +0000
Re: Reference Rustom Mody <rustompmody@gmail.com> - 2014-03-04 08:24 -0800
Re: Reference Chris Angelico <rosuav@gmail.com> - 2014-03-05 02:25 +1100
Re: Reference Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2014-03-05 14:37 +0100
Re: Reference Steven D'Aprano <steve@pearwood.info> - 2014-03-04 03:59 +0000
Re: Reference Ben Finney <ben+python@benfinney.id.au> - 2014-03-04 09:17 +1100
Re: Reference Roy Smith <roy@panix.com> - 2014-03-03 18:02 -0500
Re: Reference Chris Angelico <rosuav@gmail.com> - 2014-03-04 10:09 +1100
Re: Reference Steven D'Aprano <steve@pearwood.info> - 2014-03-04 04:38 +0000
Re: Reference Terry Reedy <tjreedy@udel.edu> - 2014-03-03 13:48 -0500
Re: Reference Steven D'Aprano <steve@pearwood.info> - 2014-03-04 03:45 +0000
Re: Reference Alexander Blinne <news@blinne.net> - 2014-03-04 13:55 +0100
Re: Reference Chris Angelico <rosuav@gmail.com> - 2014-03-05 01:06 +1100
Re: Reference Alexander Blinne <news@blinne.net> - 2014-03-04 22:53 +0100
Re: Reference Chris Angelico <rosuav@gmail.com> - 2014-03-05 09:01 +1100
Page 5 of 5 — ← Prev page 1 2 3 4 [5]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-03-05 02:25 +1100 |
| Message-ID | <mailman.7723.1393946767.18130.python-list@python.org> |
| In reply to | #67642 |
On Wed, Mar 5, 2014 at 2:19 AM, Jerry Hill <malaclypse2@gmail.com> wrote: > Out of curiosity, do you think we should be doing truth checking with > 'is'? True and False are singletons, and it seems to me that the > justification for idenity versus equality should be just as strong > there, but I don't think I've ever seen anyone even suggest that. Normal truth testing is done like this: if cond: This isn't truth testing, this is checking the identity of what's in cond: if cond is True: And that's specifically testing for something much tighter than truthiness. As you can see from my stats above, that's actually fairly rare. Usually you'd just accept that True, 1, "yes", [1,2,3], and 1.2345 are all equally true. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2014-03-05 14:37 +0100 |
| Message-ID | <mailman.7822.1394026653.18130.python-list@python.org> |
| In reply to | #67642 |
Op 04-03-14 16:25, Chris Angelico schreef: > On Wed, Mar 5, 2014 at 2:19 AM, Jerry Hill <malaclypse2@gmail.com> wrote: >> Out of curiosity, do you think we should be doing truth checking with >> 'is'? True and False are singletons, and it seems to me that the >> justification for idenity versus equality should be just as strong >> there, but I don't think I've ever seen anyone even suggest that. > Normal truth testing is done like this: > > if cond: In an other language with real booleans where an if only accepts a boolean that would be true. In python this is testing for "something." > This isn't truth testing, this is checking the identity of what's in cond: > > if cond is True: > > And that's specifically testing for something much tighter than > truthiness. As you can see from my stats above, that's actually fairly > rare. Usually you'd just accept that True, 1, "yes", [1,2,3], and > 1.2345 are all equally true. No I usually don't accept that. A number different from 0 is not the same as a none-empty list. I usally don't want to treat them the same. -- Antoon Pardon
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2014-03-04 03:59 +0000 |
| Message-ID | <53154f85$0$2923$c3e8da3$76491128@news.astraweb.com> |
| In reply to | #67593 |
On Mon, 03 Mar 2014 17:02:14 -0500, Jerry Hill wrote:
> On Mon, Mar 3, 2014 at 4:51 PM, Tim Chase
> <python.list@tim.thechases.com> wrote:
>> There are a couple use-cases I've encountered where "is" matters:
>>
>> 1) the most popular:
>>
>> if foo is None:
>> do_stuff()
>
> I know this is the one that always comes up, but honestly, I feel like
> "is" doesn't matter here. That code would be just as correct if it was
> written as:
>
> if foo == None:
> do_stuff()
>
> The only time it would give you a different result from the "is" version
> is if foo was bound to an object that returned True when compared with
> None. And if that were the case, I'm still not convinced that you can
> tell from looking at those two lines of code which one is buggy,
It's all about the intention of the code.
Are you trying to test whether an object *is* the None singleton, and no
other value? Then use "is", don't use == because it is subject to false
positives (returning True for some objects that aren't actually None).
Or do you want to test whether an object merely happens to have the same
value as None? Then use == and be glad.
Personally, I have never written code that looks like this:
def spam(a, b=None):
"""Spamify a with optional b.
If b is None ***OR SOMETHING THAT COMPARES EQUAL TO NONE***
or not supplied, use extra-yummy spammification mode.
"""
if b == None: ...
But if I ever did want to do that, I can.
Since None is a singleton null-object, something with no state and no
behaviour, we normally treat it as a sentinel, in which case an identity
test is usual. I can't really think of any good reason to treat it as a
value where I would want to use an equality test.
> except
> for the fact that there has been 20 years of custom saying that
> comparing to None with equality is wrong.
It's not *necessarily* wrong, merely wrong the 99.9998% of the time that
you want to treat None as a sentinel.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2014-03-04 09:17 +1100 |
| Message-ID | <mailman.7669.1393885090.18130.python-list@python.org> |
| In reply to | #67561 |
Jerry Hill <malaclypse2@gmail.com> writes: > if foo == None: > do_stuff() > > The only time it would give you a different result from the "is" > version is if foo was bound to an object that returned True when > compared with None. That's right. Python provides this singleton and then recommends you compare with ‘is’, precisely to protect against pathological cases like a “return True when compared for equality with None” data type. Using ‘if foo is None’ means you don't even have to spend time worrying about such cases. > And if that were the case, I'm still not convinced that you can tell > from looking at those two lines of code which one is buggy, except for > the fact that there has been 20 years of custom saying that comparing > to None with equality is wrong. Yes. And because of that widespread convention, it's much more correct to compare against None with ‘is’. -- \ “Always do right. This will gratify some people, and astonish | `\ the rest.” —Mark Twain | _o__) | Ben Finney
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2014-03-03 18:02 -0500 |
| Message-ID | <roy-F1E46D.18020403032014@news.panix.com> |
| In reply to | #67600 |
In article <mailman.7669.1393885090.18130.python-list@python.org>, Ben Finney <ben+python@benfinney.id.au> wrote: > That's right. Python provides this singleton and then recommends you > compare with ‘is’, precisely to protect against pathological cases like > a “return True when compared for equality with None” data type. Going off on a tangent, I've often wished Python provided more kinds of None-ness. I'll often write: def f(arg=None): whatever where it would be nice to differentiate between "this was called with no arguments" and "this was called with an argument of None". Sure, I can work around that with things like **kwargs, and then test "args" in kwargs vs. kwargs["args"] is None but that always feels clumsy. It also makes the function declaration less sell-describing. "Hmmm, let's see what help() says. Oh, gee, I can pass it some stuff".
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-03-04 10:09 +1100 |
| Message-ID | <mailman.7680.1393888187.18130.python-list@python.org> |
| In reply to | #67613 |
On Tue, Mar 4, 2014 at 10:02 AM, Roy Smith <roy@panix.com> wrote:
> In article <mailman.7669.1393885090.18130.python-list@python.org>,
> Ben Finney <ben+python@benfinney.id.au> wrote:
>
>> That's right. Python provides this singleton and then recommends you
>> compare with ‘is’, precisely to protect against pathological cases like
>> a “return True when compared for equality with None” data type.
>
> Going off on a tangent, I've often wished Python provided more kinds of
> None-ness. I'll often write:
>
> def f(arg=None):
> whatever
>
> where it would be nice to differentiate between "this was called with no
> arguments" and "this was called with an argument of None".
That's why you have your own sentinel.
_NONE_PASSED=object()
def f(arg=_NONE_PASSED):
if f is not _NONE_PASSED: pass
ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2014-03-04 04:38 +0000 |
| Message-ID | <531558ac$0$2923$c3e8da3$76491128@news.astraweb.com> |
| In reply to | #67613 |
On Mon, 03 Mar 2014 18:02:04 -0500, Roy Smith wrote:
> In article <mailman.7669.1393885090.18130.python-list@python.org>,
> Ben Finney <ben+python@benfinney.id.au> wrote:
>
>> That's right. Python provides this singleton and then recommends you
>> compare with ‘is’, precisely to protect against pathological cases like
>> a “return True when compared for equality with None” data type.
>
> Going off on a tangent, I've often wished Python provided more kinds of
> None-ness. I'll often write:
>
> def f(arg=None):
> whatever
>
> where it would be nice to differentiate between "this was called with no
> arguments" and "this was called with an argument of None". Sure, I can
> work around that with things like **kwargs,
That's the hard way. The easy way is:
_SENTINEL = object()
def f(arg=_SENTINEL):
if arg is _SENTINEL:
...
If you really cared, you could implement your own None_ish_Type and
create as many named sentinels as you wish.
--
Steven
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2014-03-03 13:48 -0500 |
| Message-ID | <mailman.7654.1393872546.18130.python-list@python.org> |
| In reply to | #67520 |
On 3/3/2014 4:42 AM, ast wrote: > Consider following code: > >>>> A=7 >>>> B=7 >>>> A is B The 'is' operator has three uses, two intended and one not. In production code, 'is' tests that an object *is* a particular singular object, such as None or a sentinel instance of class object. In test code, 'is' can also be used to test details of a particular implementation, such as pre-allocation of small ints. New python programmers also use it to confuse themselves. -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2014-03-04 03:45 +0000 |
| Message-ID | <53154c73$0$2923$c3e8da3$76491128@news.astraweb.com> |
| In reply to | #67573 |
On Mon, 03 Mar 2014 13:48:39 -0500, Terry Reedy wrote: > On 3/3/2014 4:42 AM, ast wrote: > >> Consider following code: >> >>>>> A=7 >>>>> B=7 >>>>> A is B > > The 'is' operator has three uses, two intended and one not. In > production code, 'is' tests that an object *is* a particular singular > object, such as None or a sentinel instance of class object. In test > code, 'is' can also be used to test details of a particular > implementation, such as pre-allocation of small ints. New python > programmers also use it to confuse themselves. +1 QOTW -- Steven
[toc] | [prev] | [next] | [standalone]
| From | Alexander Blinne <news@blinne.net> |
|---|---|
| Date | 2014-03-04 13:55 +0100 |
| Message-ID | <5315cd4b$0$6670$9b4e6d93@newsspool2.arcor-online.net> |
| In reply to | #67573 |
Am 03.03.2014 19:48, schrieb Terry Reedy:
> The 'is' operator has three uses, two intended and one not. In
> production code, 'is' tests that an object *is* a particular singular
> object, such as None or a sentinel instance of class object.
Just a bit of statistics on this one from a recent small project:
<13:51:20> alex@firefly$ grep ' is ' *.py | wc
65 415 3234
<13:51:35> alex@firefly$ grep ' is None' *.py | wc
43 243 1948
<13:51:40> alex@firefly$ grep ' is not None' *.py | wc
21 167 1241
<13:51:44> alex@firefly$ grep ' is False' *.py | wc
1 5 45
No other uses if 'is' found in almost 3 KLOC...
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-03-05 01:06 +1100 |
| Message-ID | <mailman.7714.1393941984.18130.python-list@python.org> |
| In reply to | #67669 |
On Tue, Mar 4, 2014 at 11:55 PM, Alexander Blinne <news@blinne.net> wrote: > Am 03.03.2014 19:48, schrieb Terry Reedy: >> The 'is' operator has three uses, two intended and one not. In >> production code, 'is' tests that an object *is* a particular singular >> object, such as None or a sentinel instance of class object. > > Just a bit of statistics on this one from a recent small project: > > <13:51:20> alex@firefly$ grep ' is ' *.py | wc > 65 415 3234 > <13:51:35> alex@firefly$ grep ' is None' *.py | wc > 43 243 1948 > <13:51:40> alex@firefly$ grep ' is not None' *.py | wc > 21 167 1241 > <13:51:44> alex@firefly$ grep ' is False' *.py | wc > 1 5 45 > > No other uses if 'is' found in almost 3 KLOC... Lemme spin you up a different way of doing it, which actually looks for the operators. https://github.com/Rosuav/ExceptExpr/blob/master/find_except_expr.py Run across the Python stdlib, that tells me there are 4040 uses of is/is not, of which 16 compare against False, 18 against True (see? Python has a bias for truth above falsehood!), and 3386 against None. The other 620 are probably mostly sentinel objects, but I didn't look at them. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Alexander Blinne <news@blinne.net> |
|---|---|
| Date | 2014-03-04 22:53 +0100 |
| Message-ID | <53164b54$0$6663$9b4e6d93@newsspool2.arcor-online.net> |
| In reply to | #67677 |
Am 04.03.2014 15:06, schrieb Chris Angelico: > https://github.com/Rosuav/ExceptExpr/blob/master/find_except_expr.py I have always found it quite nice that the python parser is so easy to use from within python itself. > Run across the Python stdlib, that tells me there are 4040 uses of > is/is not, of which 16 compare against False, 18 against True (see? > Python has a bias for truth above falsehood!), and 3386 against None. I think i will have to rephrase my "is False" condition to make it more truthy :)
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2014-03-05 09:01 +1100 |
| Message-ID | <mailman.7753.1393970506.18130.python-list@python.org> |
| In reply to | #67732 |
On Wed, Mar 5, 2014 at 8:53 AM, Alexander Blinne <news@blinne.net> wrote: > Am 04.03.2014 15:06, schrieb Chris Angelico: >> https://github.com/Rosuav/ExceptExpr/blob/master/find_except_expr.py > > I have always found it quite nice that the python parser is so easy to > use from within python itself. Yes. Until I put together the original version of that, to search for PEP 463 translation candidates, I'd never used the ast module other than for literal_eval. It's marvelously powerful. >> Run across the Python stdlib, that tells me there are 4040 uses of >> is/is not, of which 16 compare against False, 18 against True (see? >> Python has a bias for truth above falsehood!), and 3386 against None. > > I think i will have to rephrase my "is False" condition to make it more > truthy :) if x is False: --> if not x: ChrisA
[toc] | [prev] | [standalone]
Page 5 of 5 — ← Prev page 1 2 3 4 [5]
Back to top | Article view | comp.lang.python
csiph-web