The number of times I've seen code written that reads well and passes less
trained code reviews easily such as:
if check_num and mystring and mystring.isdigit:
has increased beyond what I can count on one hand. The code executes and
even does the right thing part of the time.
Proposal: any method that returns a boolean on builtins like bytes and
unicode objects be turned into a property in a future python version. That
way the above mistake would happen less often. mystring.isdigit would be a
boolean rather than a method reference that is always True.
There are many ways of detecting the above beyond code review such as making
a pylink or pychecker type thing flag them, having proper unittest coverage
that tests both conditions, etc. But those are not always in place.
A hack could be done today to have these behave as both functions and
properties by having the property return a callable bool derived class that
returns itself. But that seems a bit too cool yet gross...
> On 2010-10-25 04:37, Guido van Rossum wrote:
>> This should not require threads.
>> Here's a bare-bones sketch using generators:
On Mon, Oct 25, 2010 at 3:19 AM, Jacob Holm <jh(a)improva.dk> wrote:
> If you don't care about allowing the funcs to raise StopIteration, this
> can actually be simplified to:
Indeed, I realized this after posting. :-) I had several other ideas
for improvements, e.g. being able to pass an initial value to the
reduce-like function or even being able to supply a reduce-like
function of one's own.
> More interesting (to me at least) is that this is an excellent example
> of why I would like to see a version of PEP380 where "close" on a
> generator can return a value (AFAICT the version of PEP380 on
> http://www.python.org/dev/peps/pep-0380 is not up-to-date and does not
> mention this possibility, or even link to the heated discussion we had
> on python-ideas around march/april 2009).
Can you dig up the link here?
I recall that discussion but I don't recall a clear conclusion coming
from it -- just heated debate.
Based on my example I have to agree that returning a value from
close() would be nice. There is a little detail, how multiple
arguments to StopIteration should be interpreted, but that's not so
important if it's being raised by a return statement.
> Assuming that "close" on a reduce_collector generator instance returns
> the value of the StopIteration raised by the "return" statements, we can
> simplify the code even further:
> def reduce_collector(func):
> outcome = yield
> except GeneratorExit:
> return None
> while True:
> val = yield
> except GeneratorExit:
> return outcome
> outcome = func(outcome, val)
> def parallel_reduce(iterable, funcs):
> collectors = [reduce_collector(func) for func in funcs]
> for coll in collectors:
> for val in iterable:
> for coll in collectors:
> return [coll.close() for coll in collectors]
> Yes, this is only saving a few lines, but I find it *much* more readable...
I totally agree that not having to call throw() and catch whatever it
bounces back is much nicer. (Now I wish there was a way to avoid the
"try..except GeneratorExit" construct in the generator, but I think I
should stop while I'm ahead. :-)
The interesting thing is that I've been dealing with generators used
as coroutines or tasks intensely on and off since July, and I haven't
had a single need for any of the three patterns that this example
happened to demonstrate:
- the need to "prime" the generator in a separate step
- throwing and catching GeneratorExit
- getting a value from close()
(I did have a lot of use for send(), throw(), and extracting a value
In my context, generators are used to emulate concurrently running
tasks, and "yield" is always used to mean "block until this piece of
async I/O is complete, and wake me up with the result". This is
similar to the "classic" trampoline code found in PEP 342.
In fact, when I wrote the example for this thread, I fumbled a bit
because the use of generators there is different than I had been using
them (though it was no doubt thanks to having worked with them
intensely that I came up with the example quickly).
So, it is clear that generators are extremely versatile, and PEP 380
deserves several good use cases to explain all the API subtleties.
BTW, while I have you, what do you think of Greg's "cofunctions" proposal?
--Guido van Rossum (python.org/~guido)
This morning I tried to fix an issue for a while before I realized I
had a circular import. This issue is not obvious because you get a
cryptic error, like an AttributeError and it can tak a while before
I don't know of this was mentioned before, or how hard it would be.
But it would be nice if Python had a specific "CircularImportError"
raised in that case, or something..
That would be a fabulous hint for developers.
Tarek Ziadé | http://ziade.org
Now that we've developed 2to3 and 3to2 I've started wondering "what next?"
and realized that we could use a 3to3 tool to apply the relatively few and
relatively simple sets of code changes to deal with library reorganizations,
renaming, parameter changes, default behavior changes, other deprecations
that have an equivalent, etc. The list of migrations to go between any
given 3.x to another 3.x release would likely be pretty small.
Just tossing the idea out there incase someone is interested. I expect the
hard work is already done.
I would like to see python's doc-string creation extended to allow for %
style string substitution.
This allows for patterns that keep doc-strings up-to-date without certain
types of boilerplate maintenance. For instance:
Including additional information from the module:
RED = (255, 0, 0)
color could be any:
""" % '\n\t'.join('Color.' + color for color in publicDir(Colors))
Including docs of other functions
"Keeping the docstring with the function that does the work, so it's more
likely to keep up to date"
"%s" % _localFunction.__doc__
Executing code to retrieve a doc-string is considered a security
vulnerability. (Right now only the abstract syntax tree is used to get
In theory this could be backwards incompatible with existing code... but
that code would have to be relying on the side effect of some string
substitution line without doing anything with the new string - yuck.
Aim - Zac256FL
`issubclass(1, list)` raises an Exception, complaining that `1` is not a
class. This is wrong in my opinion. It should just return False.
Use case: I have an object which can be either a list, or a string, or a
callable, or a type. And I want to check whether it's a sub-class of some
So I don't think I should be taking extra precautions before using
`issubclass`: If my object is not a subclass of the given base class, I
should just get `False`.
Let's recall Guido's old Computer Programming for Everybody (CP4E) proposal.
Nowadays that Python is established, it's high time to push Python
into education, especially first programming language education. I
think, in the modern world it means pre-school.
Now the larger part of the world's children doesn't learn English
before school, therefore we need to have truly localized Python.
Some might recall a Python derivative demo with unicode variable names
I think we ought to go further. For example, consider imaginary
language pig latin:
"""This does that""" --> """Thiso acto thato""" # docstrings
__version__ = (1,2,3) --> __versio__ = (1,2,3) # variable names
import time --> importo chrono # standard module names
def foo(): pass --> defo foo(): passo # Python keywords
"foo".upper() --> "foo".uppero() # standard library
raise Xx("undefined") --> raisio Xx("indifinito") # errors
#!/usr/bin/python --> #!/usr/bin/pythono # executable name
#!/usr/bin/python --> #!/usero/binaro/pythono # name and path
Of course there are concerns for many languages:
Each language needs to establish stable translations for keywords,
basic types, standard modules, methods in standard modules, etc.
Some languages don't support word spaces natively
Some languages have different punctuation rules, e.g. comma for decimal point
Some languages use different quotes
RTL languages spell words RTL yet (some/all?) spell numbers LTR
Hopefully none has to recreate 10,000-separator system ;-)
Anyhow, it's not the issue of core Python to support particular
languages, what is needed is:
the concept that this is needed, and
the base where from a particular localization can evolve from
Here, a fun example, how Python might look like in
google-translate-simplified-chinese. Blame google, not me as I know
very little about this language.
"""This does that""" --> """这是""" # docstrings
__version__ = (1,2,3) --> __版本__ = (1,2,3) # variable names
import time --> 进口 时间 # standard module names
def foo(): pass --> 业 美孚（）： 通过 # Python keywords
"foo".upper() --> “富” 上层（） # standard library
raise Xx("undefined") --> 提高。二十（“未定义”） # errors
#!/usr/bin/python --> #!/usr/bin/蛇 # executable name
#!/usr/bin/python --> #!/用户/二进制/蛇 # name and path
I track this here and will update with the received feedback: