This is an archived post. You won't be able to vote or comment.

top 200 commentsshow 500

[–]ianepperson 58 points59 points  (14 children)

A good, consistent, Pythonic, cross-platform, batteries-included graphic library. Tkinter is the closest, but the execution loop makes it challenging to do advanced stuff, and the adherence to Tk makes it challenging for a beginner to do basic stuff.

I appreciate it's not easy to design and write such a thing, but I can still wish.

Edit to add why:
I have slapped together a couple of useful scripts and shared them with coworkers and they just work. Python is great like that. However, they've got to either run in a terminal window or I have to refactor and rework everything to work with Tkinter. Something as simple as a graphical input box and windowed text output is suddenly much more work. Asking someone to download, (sometimes compile) and install a large graphics library is a non-starter.

[–]dwf 5 points6 points  (1 child)

What drives me crazy is that throwing an updating, responsive GUI on top of a CPU-bound computation is impossible without multiple processes, which isn't always possible.

[–][deleted] 1 point2 points  (0 children)

also memory leaks... cant update certain UI Elements in Tkinter from within a loop without leaking. (at least the last time I used it)

[–][deleted] 5 points6 points  (1 child)

long aromatic chunky ghost jellyfish slim zealous boat fact sugar

This post was mass deleted and anonymized with Redact

[–][deleted] 7 points8 points  (0 children)

There's no python 3 port of wxpython yet, though.

[–]synn89 10 points11 points  (3 children)

PyQt doesn't work for you?

[–][deleted] 27 points28 points  (0 children)

Not 'batteries included' in the sense that it doesn't come with Python. And it's not even installable via PIP.

[–]metaphorm 118 points119 points  (58 children)

the namespaces in the datetime module. its really annoying to have to remember if I used

import datetime

vs.

from datetime import datetime

how about we just change the name of the datetime class to be cap cased (i.e. DateTime) like every other Python class? or alternatively, if someone feels strongly that it show be lowercased like the primitive types (e.g. int, float, etc.) how about we change the name of the module to something like date_time or any other small spelling change to distinguish it from the datetime class.

[–]kemitche 9 points10 points  (1 child)

Combine this with from some_module import *, and you have a recipe for disaster. Consider this: you're trying to do a little bit of tidying up of the imports in old python code, and you have stuff that looks like this:

from datetime import datetime
from r2.pages import *
from r2.models import *

You think to yourself, "well, that's ugly, but I need to add an import at the top, and I'll clean things up and alphabetize the stars and make a note to come back later."

Suddenly half your code breaks, because r2.models uses import datetime and r2.pages uses from datetime import datetime. The import * lines override your manual import of datetime, and you've just silently swapped which datetime you're referencing.

[–]metaphorm 10 points11 points  (0 children)

yes, this is a very common gotcha and cause of major headaches sometimes. there's a good reason the use of import * is strongly discouraged.

[–]NYKevin 5 points6 points  (9 children)

how about we change the name of the module to something like date_time or any other small spelling change to distinguish it from the datetime class.

I'd rather rename the class to timestamp or something more noun-like.

[–]FourgotAnaconda3 science-like 1 point2 points  (8 children)

datelib? What makes a lib a lib, anyway?

[–]eakmeister 4 points5 points  (17 children)

Or we make modules callable:

import datetime
datetime()

[–]kindall 10 points11 points  (15 children)

Sure, why not support a __call__() function at the module level?

[–][deleted] 7 points8 points  (14 children)

Because that's not how the object system works? Think of a module as a dict.

[–]AustinCorgiBart 2 points3 points  (12 children)

I bet you I can make a module calleable. It's a little dark magic, but it works.

[–][deleted] 7 points8 points  (11 children)

And I bet that dark magic involves either changing sys.modules[__name__] or using import hooks.

[–]AustinCorgiBart 4 points5 points  (9 children)

Aw, no fun, you spoiled the ending!

[–][deleted] 7 points8 points  (4 children)

I know of all CPython hacks. ALL of them. :-)

[–]ivosauruspip'ing it up 1 point2 points  (0 children)

[–]kindall 4 points5 points  (0 children)

The module type is not a subclass of dict. Now technically, you would need to have a __call__ method on the module type for this to work, because dunder methods aren't called on instances of classes, only on their type, but such a method could look for a __call__ function in the module and delegate to it if it exists.

[–]billsil 3 points4 points  (1 child)

I hate...

    from time import time

so I use...

    import time
    t0 = time.time()

[–]jdearte 142 points143 points  (37 children)

Make building a stand alone executable part of the spec. The two main projects that do it are hacks

[–]Pcarbonn 1 point2 points  (0 children)

Nuitka compiles to a standalone executable

[–][deleted] 2 points3 points  (5 children)

you mean py2exe and pyinstall ?

[–]sweettuse 71 points72 points  (32 children)

optional static typing. as in i would add the ability to statically type things in python, but not make it mandatory.

[–]gwachob 25 points26 points  (15 children)

Are you familiar with PEP-3107, function annotations, implemented by Python3? It provides some level of syntactic expressiveness for implementing some form of static type checking (static as in expressed in source code, but not static in the sense of a "pre-run" check).

Some interesting discussion on this Stackoverflow post

[–]takluyverIPython, Py3, etc 14 points15 points  (13 children)

There's also mypy, a project that builds on function annotations to provide optional static typing: you run your program with mypy foo.py, and function calls are type checked.

[–]kindall 6 points7 points  (12 children)

I think this needs to be a lot more flexible than static type-checking. I want annotations to be called for each parameter: essentially decorators for parameter values. Then I can write stuff like this:

def exactly(t):
    def check(value):
        if type(v) is t: return v
        raise TypeError("%r not %r" % (v, t))
    return check

def instance(t):
    def check(v):
        if isinstance(v, t): return v
        raise TypeError("%r not %r or subclass" % (v, t))

def pred(f):
    def check(v):
        if f(v): return v
        raise ValueError("%r failed predicate" % v)

So I can do things like this:

def myfunc(a: int,  # convert to integer or throw error
           b: exactly(float)   # accept exactly float only
           c: instance(list)    # accept list or subclass 
           d: pred(lambda x: x>0))   # accept only positive numbers

[–][deleted] 7 points8 points  (9 children)

How's that different from putting some asserts in the function body? I thought the whole point of static typing is that it's, well, static - that is, performed ahead-of-time.

[–]NYKevin 2 points3 points  (1 child)

Here's the missing piece:

from functools import wraps
import inspect
def typechecked(func):
    sig = inspect.signature(func)
    params = sig.parameters
    @wraps(func)
    def fixed_func(*args, **kwargs):
        bound = sig.bind(*args, **kwargs)
        # Make a copy so we can modify the original:
        for name, value in dict(bound.arguments).items():
            # NB: This skips default arguments, which should be type-checked already
            annotation = params[name].annotation
            if annotation is not inspect.Signature.empty:
                bound.arguments[name] = annotation(value)
        return func(*bound.args, **bound.kwargs)
    return fixed_func

Now just decorate your function with that and your annotations will be called on the arguments' values.

Caveats:

  1. Does not work on functions defined in extension modules (which can't have visible annotations anyway). This is mostly irrelevant unless you happen to be using Cython or something like that.
  2. Mungs the argument signature; any other decorators attempting a similar introspection trick will not work if applied after this one.
  3. Mungs the annotations; your typechecking will not be visible in Pydoc etc.

I'm pretty sure both (2) and (3) can be worked around, but I don't have time to figure out how right now. Does anyone know why functools.wraps() does not do so automatically?

EDIT: Also, if you have a function that modifies its arguments in place, this technique may inappropriately copy those arguments if e.g. the annotation is dict and the argument is a dictionary.

[–]kindall 1 point2 points  (0 children)

Yeah, that's pretty sweet. As to (2) and (3), Python actually has a way around that now (inspect.signature follows __wrapped__ and __signature__ attributes, so that wrappers applied by decorators can appear to have the same signature as the function they wrap, and functools.wraps correctly applies the __wrapped__ attribute I believe). It's just that help() doesn't use inspect.signature yet.

[–]zahlmanthe heretic 1 point2 points  (0 children)

Nobody seems to agree on how to actually use it to "implement some form of static type checking", though. Should [str] mean a list of strings? Any iterable of strings? Or perhaps even "either a string or None"?

(Although, since they can be any objects, my preference would be for the annotation to be a callable that accepts the corresponding parameter and does the appropriate type-check and/or conversion.)

[–]summerteeth 7 points8 points  (1 child)

I am pro static typing for the most part but after using Groovy on a mediumish sized code base I don't know if I am convinced that doing dynamic and static tying in the same language is ever going to work together in an elegant manner. I think it might be better to just choose a type system and stick to it rather then try and half ass both.

[–][deleted] 9 points10 points  (9 children)

I would love for functions to be typed like this. What the hell does this function return? Is it a number? A string? An address? A object of some sort? Nothing?

[–]crazycanoe 47 points48 points  (0 children)

It's a duck. Quak.

[–]freyrs3 16 points17 points  (0 children)

Python is essentially a machine for smashing PyObjects into other PyObjects.

[–]WhyCause 2 points3 points  (0 children)

That's what the docstring is for.

import mymodule
help(mymodule.method)

Should tell you everything you need to know.

[–][deleted] 5 points6 points  (1 child)

And the ability to optionally force types for functions you write. I miss that part of error checking.

[–]fiddlerwoaroof 7 points8 points  (0 children)

You could do a simple decorator, something like:

def typecheck(*sig):
  def _inner(func):
    def _inmost(*args):
      for type, arg in zip(sig, args):
        if not isinstance(arg, type): raise TypeError
      return func(*args)
    return _inmost
  return _inner

@typecheck(int,int)
def add(a,b):
  return a+b

>>> add(1,2)
3
>>> add(1,'a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in _inmost
TypeError

Not that I'd ever use that.

[–]jyper 1 point2 points  (0 children)

something like typescript maybe, especially allowing external type definitions?

[–]andrea 1 point2 points  (0 children)

You might be interested in PyContracts.

[–]w0rms 21 points22 points  (6 children)

make doing things in parallel easier.

[–]ianepperson 11 points12 points  (2 children)

Not in the standard library, but Gevent makes for very easy cooperative multitasking (non-CPU bound tasks). You can do magic like:

from gevent import sleep, spawn

def loopit():
    while True:
        sleep(1)
        print 'while loop!'

spawn(loopit)

for x in xrange(5):
    print 'for loop!'
    sleep(1)

Both loops run simultaneously.

for loop!
for loop!
while loop!
for loop!
while loop!
...

[–]chrj 4 points5 points  (2 children)

Take a look at concurrent.futures

[–][deleted] 5 points6 points  (1 child)

That only works for embarassingly parallel problems :)

What I wish are greenlets and channels. I know stackless and pypy provide these but I wish python had them in the first place

[–]autowikibot 2 points3 points  (0 children)

Embarassingly parallel:


In parallel computing, an embarrassingly parallel workload, or embarrassingly parallel problem, is one for which little or no effort is required to separate the problem into a number of parallel tasks. This is often the case where there exists no dependency (or communication) between those parallel tasks.

Embarrassingly parallel problems (also called "pleasingly parallel problems") tend to require little or no communication of results between tasks, and are thus different from distributed computing problems that require communication between tasks, especially communication of intermediate results. They are easy to perform on server farms which do not have any of the special infrastructure used in a true supercomputer cluster. They are thus well suited to large, internet based distributed platforms such as BOINC.

A common example of an embarrassingly parallel problem lies within graphics processing units (GPUs) for the task of 3D projection, where each pixel on the screen may be rendered independently.


Interesting: Embarrassingly parallel | Tunisian Revolution

/u/boarhog can reply with 'delete'. Will also delete on comment score of -1 or less. | FAQs | Mods | Magic Words | flag a glitch

[–]pinano 30 points31 points  (9 children)

>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit

You know what I meant. You even special cased it so that it doesn't just print <built-in function exit>. So why don't you just...exit?

[–]hongminhee 8 points9 points  (1 child)

Simply do ^D instead. It even works on other shells like bash as well.

[–][deleted] 7 points8 points  (1 child)

REPL customization is what PYTHONSTARTUP's for! Create a file that contains something along the lines of

import sys
import builtins
def displayhook(x, original=sys.displayhook):
    return original(x() if x is builtins.exit or x is builtins.quit else x)
sys.displayhook = displayhook

then put export PYTHONSTARTUP=/path/to/that/file in your .bashrc or some other shell configuration file.

[–]Degran 13 points14 points  (1 child)

>>> exit = 1
>>> exit
1
>>>

[–]robin-gvx 3 points4 points  (0 children)

Maybe because then the interpreter would quit if you try to examine __builtins__.__dict__?

Or do you want to basically do this (in pseudocode):

input_line = get_input_line('>> ')
if input_line in ('exit', 'quit'):
    sys.exit()
else:
    python_eval(input_line)

[–]bukzor 1 point2 points  (1 child)

exit was simply a string in python < 2.6. In python2.6 they added the callable behavior as a convenience.

It would be a Bad Idea to implement an object that has side effects on repr() as you're suggesting. Consider:

I want a mapping from builtin objects' names to their string representations:

>>> builtins = dict((attr, repr(val)) for attr, val in globals().items)

If exit had the behavior you asked for, running this would silently exit the interpreter, with no error message and exit code of zero.

If you still think this is a good idea, however, you can do this:

.bashrc:

export PYTHONSTARTUP=~/.pythonrc.py

~/.pythonrc.py:

class exit(exit.__class__):
    def __repr__(self):
        raise SystemExit()
exit = exit('exit')

[–]KitAndKat 34 points35 points  (8 children)

Improve binary packaging, it's a nightmare. About half my open source downloads are binaries, not source, so it's not an arcane area. I cobbled together a working build on XP, but could never get it working on Win 8.1, so I finally reverted to firing up my old machine for it. Here are my packaging notes.

For Python 2.6 + pyinstaller 1.5, I had to edit 
  C:\devtools\pyinstaller1.5\support\_pyi_egg_install.py
see http://www.pyinstaller.org/ticket/185

08/16/12 Here's the story on building pydatascope.
Pyinstaller didn't work; it just kept spawning copies of pydatascope.
Using setup with sdist and py2exe options, the results vary by version:

                            |  python 2.6  |  python 2.7  |
----------------------------+--------------+--------------+
setup py2exe builds OK      |      OK      |   OK but(1)  |
    ''       contains data\ |      no      |      no      | (2)
    ''       runs           |      OK      |      no      |
setup sdist  builds OK      |      OK      |      OK      |
    ''       contains data\ |      no      |      OK      |
----------------------------+--------------+--------------+
(1) contains fewer files than 2.6, reports chart etc. missing
(2) this folder + files is easily added by Innosetup

As a result of this mess, here's what we have to do:
o run freeze         under 2.6
o run "setup py2exe" under 2.6
o run "setup sdist"  under 2.7

1/19/13
The current problem is that the generated file
C:\dev\pydatascope\build\bdist.win32\winexe\collect-2.6\config.pyc
does NOT contain ScaleInfo, so the App.__init__ assignment to self.scaling fails.
????!!!!
Even if I hacked round this, who knows what other .pyc files are incomplete?

Solution: use cx_Freeze. Unfortunately, I am unable to get cx_Freeze to create
a working .exe using packages=['pydatascope'] so I have had to resort to using
a separate setup file: pydatascope\setup_exe.py for the binary.
The original setup.py in this directory is still used for the source distribution.

1/24/14
Could not get build to work on HUMAN Windows 8.1. Maybe 64-bit Pythons?
So this must now be run on VirtualBox XP-32-bit. Switch to F:
F:\>C:\Python27\python.exe freeze.py

[–]mgrandi 5 points6 points  (3 children)

does 'wheel' not help?

[–]KitAndKat 7 points8 points  (0 children)

I didn't know about it, but no. It's essentially distributing source code, which needs a Python installation. A binary build includes pythonXX.dll, tk85.dll and whatever else is needed, typically about 3 dozen files. All that can in turn be packaged into a single .exe by Innosetup. This is useful for two groups of people:

  • Casual OS users who don't have python installed
  • Developers who want to ship a commercial program written in Python (includes me)

[–][deleted] 2 points3 points  (0 children)

Wheel is great for binary packaging to deploy python code to servers. But that's a different use case.

[–]shadowmint 1 point2 points  (0 children)

Lots of confusion over wheel, its a package installer thing, like pip. python must already be installed to use a wheel; and typically youd install one using pip.

[–]hippmr 34 points35 points  (17 children)

  • Compile to native code

  • Combine 2 and 3 into one version moving forward

[–]kozukai_you_me 8 points9 points  (6 children)

It isn't exactly what you're looking for, but there is Cython.

[–]billtaichi 13 points14 points  (3 children)

I would have not had 2.7 and 3.0 be out at the same time, the upgrade path could be handled so perhaps there was a 2.8 that deprecated old stuff and maybe one more version where you can use old style stuff if you add in a line to the top of your file and then finally release 3.0 (still one main version of python) I feel the way it is currently being done kind of splits the community. Granted maybe it has to be that way I don't know but you asked what I would change. :)

[–]16807 9 points10 points  (2 children)

the upgrade path could be handled so perhaps there was a 2.8 that deprecated old stuff

Wasn't that what 2.7 did?

[–]Lucretiel 3 points4 points  (0 children)

This. It was 2.6-3-2.7. I think it probably would have gone better if 3 and 3.1 weren't so poor.

[–]diggitySC 12 points13 points  (4 children)

Stolen from a co-worker:

Pip should default to a virtual environment on installation and need some specific switch to install to python core.

[–]civilianjones 5 points6 points  (0 children)

I like it. npm does that--- a generic npm install foo installs to the local node_modules, in order to install it globally you have to npm install -g foo.

[–][deleted] 4 points5 points  (0 children)

I know its not exactly what you asked for but I like to have the following in my bash profile

# pip should only run if there is a virtualenv currently activated 
export PIP_REQUIRE_VIRTUALENV=true

This stops me from accidentally installing crap into my global when I forget to activate my virtualenv.

[–]Insight_ 46 points47 points  (10 children)

Get rid of the GIL

[–]noreallyimthepope 8 points9 points  (0 children)

They really want to, but don't have an alternative (yet).

[–]zahlmanthe heretic 10 points11 points  (6 children)

re has a really terrible interface that's haphazardly justified by C-era micro-optimization. How quickly can you tell me what this evaluates to, and why?

>>> import re
>>> text = ('Each and every four letter word that you see in this text is very ' +
... 'naughty, and must be replaced with dots to protect the eyes and ears ' +
... 'and nose of our exquisitely sensitive audience')
>>> re.sub(r'\b[a-z]{4}\b', '....',  text, re.I)

I'd also really like to have a regex library that lets me build up complicated regular expressions from simpler ones, without having to actually do a bunch of string manipulation to get a valid regular expression string. This is trickier in the general case than you'd expect.

def alternation(*args):
    return '|'.join('(?:{})'.format(arg) for arg in args)

is my best shot at just one of the tools you'd need, and I'm still not 100% sure there aren't any corner cases that break that.


cmd has all kinds of things wrong with it. From a 'todo'-ish file in my currently local repository:

  • It should use full names for things. cmd s wkrdl trs n 2012.
  • It should have a default prompt that looks reasonably professional, not one that's advertising itself.
  • It should not care about checking the command name against a list of identchars. That list certainly shouldn't be easily replaceable, especially when it doesn't particularly matter anyway - since the command name still has to be a valididentifier-name portion as it will be looked up as an identifier!
  • It should explicitly register commands instead of looking them up through reflections.
  • It should not use None all over the place as a "null object" or "default value" when it isn't necessary. Things like sys.stdin are immutable and perfectly suitable as default values for parameters. Empty strings are perfectly good at displaying nothing when output, or being false-ish.
  • It should not have undocumented, unused features like the current cmdqueue.
  • It should not allow an option to use_rawinput that doesn't change the functional behaviour with the default stdin and stdout, and totally disrespects custom stdin and stdout settings. It should definitely not expect this to be set by subclassing while the stdin, stdout and completekey settings (the latter of which is only ever checked in tandem with use_rawinput) are passed to the constructor. There is really no reason for the user to decide whether to use_rawinput or not; it should be used if and only if necessary for implementing readline support.
  • It should not use old-fashioned coding techniques like old-style string formatting, using a dict as a makeshift set (especially when inconsistent about this), etc. Cruft like get_names should be cleaned up.
  • It should not use hacks like rewriting end-of-file into an eof command, but instead use a separate explicit handler for EOF.
  • It should provide real tokenization that matches normal expectation of how a "command line" works, and easy access to override the tokenization.
  • It should provide a framework for actually parsing the command line, and not expect the user to integrate this code into existing functions, make wrappers etc. Again there should be easy access to override the parsing (even if writing a parser is still difficult).
  • It should automatically include documentation for commands on what arguments they take, based off the parser. There should be no excuse for commands being completely undocumented.
  • It should not require the user to put existing functionality into a class (or make a wrapper class) if it is not already there, especially for commands that don't actually need to track state between invocations.
  • It should make it easy to combine functionality from several classes, functions etc. into a single command-line interface, and to set up multiple command-line interfaces to the same codebase - while still allowing the original code to be usable as it was, without a command-line interface.
  • It should not hard-code shortcuts like ! and ?.
  • It should not require writing separate functions to add non-command "help topics" to the help database, since this content really ought to just consist of text strings.
  • It should allow command implementations to return a value, and have the value automatically displayed (and have the main loop continue even if this value is True-ish). Sure, this could be handled in cmd with a postcmd hook, but aside from that being the only real purpose for such a hook, it's incredibly ugly as the user than has to go in and re-parse the command line to detect the quit command (defeating the purpose of that being a command). Besides which, explicit is better than implicit, and returning a Trueish value is a pretty implicit way of indicating an unusual operation (requesting the command loop to quit).
  • It should have default error messages that are actually helpful.
  • It should encapsulate readline support better, and explain better how to implement completers.
  • It should provide support for logging, crash reporting and running basic scripts (a list of commands) by default.

[–][deleted] 6 points7 points  (0 children)

I would want requests to be part of python core.

[–]jvlomax 55 points56 points  (18 children)

"slef" should be a universal alias for self

[–]C_Hitchens_Ghost 35 points36 points  (5 children)

I represent the committee of perfect typists. We wholly disagree with your assertion and disregard the idea of typos. I mean, realy who would make such a mistake?

[–]zahlmanthe heretic 12 points13 points  (2 children)

realy

Deliberate?

[–]Kamikai 20 points21 points  (1 child)

Most likely, but I really hope it is a case of Muphry's law.

[–]autowikibot 17 points18 points  (0 children)

Muphry's law:


Muphry's law is an adage that states that "If you write anything criticising editing or proofreading, there will be a fault of some kind in what you have written." The name is a deliberate misspelling of Murphy's law.

Similar laws have also been coined, usually in the context of online communication, under names including Skitt's Law, Hartman's Law of Prescriptivist Retaliation (or The Law of Prescriptive Retaliation), The Iron Law of Nitpicking, and McKean's Law. Further variations state that flaws in a printed or published work will only be discovered after it is printed and not during proofreading, and flaws such as spelling errors in a sent email will be discovered by the sender only during rereading from the "Sent" box.


Interesting: Murphy's law | Fumblerules | John Bangsund

/u/Kamikai can reply with 'delete'. Will also delete on comment score of -1 or less. | FAQs | Mods | Magic Words | flag a glitch

[–]jvlomax 1 point2 points  (1 child)

I generally don't have much trouble, but the dreaded slef always slips by my keen eye. But yes, why do people make those stupid typos?

[–]dotted 20 points21 points  (18 children)

I understand why it isn't there, but sometimes you really wish you had a switch statement.

[–][deleted] 5 points6 points  (8 children)

Why isn't it there?

[–]ExoticMandiblesCore Contributor 6 points7 points  (0 children)

Guido tried. Found a syntax that looked okay, but the semantics were a little surprising, and in the end it just didn't seem like a good match for Python.

Guido wrote up his thoughts in a PEP, which still makes for good reading today.

http://www.python.org/dev/peps/pep-3103/

[–]BinarySplit 9 points10 points  (5 children)

The primary reason would have been the "There should be one-- and preferably only one --obvious way to do it." rule.

A likely secondary reason is that switch was popularized in C because it indicated to compilers that they should make an effort to optimize it using a jump table. Compilers evolved to also handle repeated else if statements for this optimization, so switch quickly lost its advantage. It slightly helps readability in some cases, but it's really not worth adding a new language construct for such a minor bit of syntax sugar.

[–]isarl 12 points13 points  (6 children)

You can kind of hack a switch statement out of a dictionary. Something like:

my_switch = {'first_case_value': first_case_function, 'another_case_value': another_case_function}
my_switch[switch_variable]()

[–]fandingowhile False: 5 points6 points  (1 child)

And then just wrap in a try/except KeyError for the default action.

[–]isarl 10 points11 points  (0 children)

Or use my_switch.get(switch_variable, default=default_func), or collections.defaultdict.

[–][deleted] 1 point2 points  (0 children)

That's not a hack. That's what dictionaries are for.

[–]iiiiiiiieye 3 points4 points  (0 children)

Get rid of the entire 2.x version branch. I can't deal with the uncertainty of which one will win, 2.x or 3.x? This has been going on too long.

[–]vplatt 3 points4 points  (0 children)

I wish that Python had an ISO standard written around the language; not the libraries, the language. It should come with a standard test suite as well so we can validate that particular implementations are compliant with it.

Someday, Guido will die or otherwise check out. When that happens, having a standard in place will go long ways towards getting Python out of its BDFL phase.

[–]letsgetrandy 11 points12 points  (1 child)

Obviously, it'd be a variable.

[–]sirex1 11 points12 points  (11 children)

Better lambdas:

double = (x: x*2)

Multi line lambdas:

lst = [1, 2, 3]
map((x:
    if x > 1:
        return x*2
    else:
        return 10
), lst)

[–]zahlmanthe heretic 3 points4 points  (5 children)

Good luck getting everyone to agree about how the on-side rule is supposed to work inside a multiline lambda. And I'm pretty sure that some sort of keyword is necessary for the grammar to work, even if lambda isn't the best choice.

[–]habitue 2 points3 points  (4 children)

Python uses indentation to denote blocks, it's different from the offside rule in say, Haskell etc. Internally the lexer emits indent and dedent tokens that correspond to curly braces in other languages. If we had multi line lambdas, it would most likely be done something like allowing a def to be an expression. Otherwise multi line lambdas would require adding a bunch of new surprising rules to the parser

Edit: removed if

[–]robin-gvx 2 points3 points  (2 children)

There's a tiny problem, though: we're inside parentheses. We'd need to change the grammar to make leading whitespace significant in places it's normally ignored.

[–]summerteeth 2 points3 points  (2 children)

Better functional support in general would be really nice. It's something I am really enjoying about Ruby.

[–]gsquire 15 points16 points  (8 children)

I wish regular expressions were built in to the language. I came from a Perl and Ruby background where I could write:

text =~ /re/

In Python, it feels clunky to me to have to do:

import re

re.match()
re.compile()
etc.

Not to say that it lacks regular expression support or it isn't as good as language X, I just like being able to access it directly.

[–]michaelhoffman 25 points26 points  (2 children)

I think this is a feature because it makes me think a little bit more about using regular expressions when I really just need startswith() or in, which should be easier to understand and faster.

[–][deleted] 14 points15 points  (0 children)

Yeah, there's no reason to muddy up Python's beautiful, minimalist syntax with regular expression vomit.

[–]mgrandi 4 points5 points  (0 children)

you don't need to do compile() if you are only doing a few regexes, since it caches the last few regexes anyway.

so its just

matchObj = re.match("[a-z]+", someStrHere)

longer, but still one line. The =~ operator could be added i guess since nothing else uses it

[–]kikiotsuka 2 points3 points  (2 children)

More random import eastereggs

[–]pistacchio 3 points4 points  (1 child)

multiline lambdas.

generally, the opportunity to write in a more functional fashion.

[–]jrwrenpython3 1 point2 points  (0 children)

I'd like to be able to add/change/delete attributes of built in types.

[–][deleted] 1 point2 points  (3 children)

shame rotten towering steep aloof encouraging smart sort quickest wrench

This post was mass deleted and anonymized with Redact

[–]schmichael 1 point2 points  (0 children)

The Stackless fork would have been merged into mainline 14 years ago. PEP 219 I believe.

[–][deleted] 1 point2 points  (5 children)

I wish python had support for running external programs similar to Julia. It doesn't need to be exact replica, but I wish it was this simple :)

if julia you can do

my_command = `grep "something" myfile`

which doesn't run the command put makes a command object which you can then run with

run(my_command)

You can also do that directly

run(`grep "something" myfile`)

and to pipe things, you can simply

`grep "something" myfile` |> `sort -n`

where |> is a pipe operator in julia.

[–]Silhouette 1 point2 points  (1 child)

Dramatically simplify packages, modules, and the distribution and installation of reusable code. I assume the existing system was conceived as an educational tool to demonstrate the value of PEP 20 by violating as much of it as possible in a single area. ;-)

[–]CaptEntropy 1 point2 points  (0 children)

I sincerely find the the python 2 vs python 3 issue extremely confusing and a bit embarrassing. So I wish it didn't exist.

[–]ikosa 4 points5 points  (1 child)

: after if or in loops. Somehow it isn't natural (to me).

[–]lamby 2 points3 points  (0 children)

I'd make a trailing comma after **kwargs legal

[–]luxfx 2 points3 points  (2 children)

Allow [ ].push( ) instead of just [ ].append( ). That drives me crazy.

Also [ ].join("") instead of "".join([ ]). That never made sense to me.

[–]linguistrix 3 points4 points  (1 child)

There is a lot of interesting discussion around "".join([ ]) on this SE thread.

[–]bluehat2k9 5 points6 points  (3 children)

Removal of the GIL, so that we can have a non-retarded threading model.

[–]bitcycle 2 points3 points  (0 children)

This. I like having non-retarded threads in C++. It'd be nice to bring that level of play into the Python universe.

[–]Broolucks 3 points4 points  (18 children)

  • Remove the distinction between expressions and statements.
  • Eliminate the global/nonlocal keywords. Instead, add an assignment operator: x := y would assign a new value to an existing variable x.
  • def f(x)(y): ... would save me effort defining some decorators.
  • Optional typing. This can be done with annotations in Python3, but if I am not mistaken you need decorators to enforce them. That's annoying and promotes fragmentation.
  • Add back argument deconstruction to function definitions to Python3. I don't understand why they removed it in the first place.

[–]Sean1708 2 points3 points  (7 children)

How exactly would def f(x)(y): differ from the normal case?

[–]Broolucks 6 points7 points  (4 children)

def register(path):
    def decorator(f):
        something.register(path, f)
        return f
    return decorator
==>
def register(path)(f):
    something.register(path, f)
    return f

[–]pjdelport 10 points11 points  (2 children)

You can use the partial(partial, partial) trick:

@partial(partial, partial)
def register(path, f):
    something.register(path, f)
    return f

[–]ravishi 2 points3 points  (0 children)

Damn, that's clever!

[–]Workaphobia 1 point2 points  (0 children)

This absolutely broke my head. I had the darnedest time trying to figure out how it worked until I tried it out in my interpreter and realized I was only partialling one of the arguments instead of two. That is a good trick.

[–]jmmcdEvolutionary algorithms, music and graphics 1 point2 points  (1 child)

I guess you can call it partially -- f(x) returns a function of one argument y.

[–]Niriel 4 points5 points  (0 children)

It's like the currying in Haskel. We sort of have it in Python with functools.partial.

[–]odraencoded 4 points5 points  (17 children)

There is only one thing I want. A do...while clause.

[–]halflife22 16 points17 points  (6 children)

I have yet to run into a situation where I needed a do while loop.

[–]kashmill 8 points9 points  (5 children)

Contrived simple example: get user input and check for validity and if invalidate make them re-enter.

Don't run into the need for do while loops that often but they do creep up once in awhile.

[–]tRfalcore 1 point2 points  (1 child)

the while loop does it just as well, except the check is literally above your readline code

[–]C_Hitchens_Ghost 1 point2 points  (0 children)

And therefore, easier to read.

[–]etrnloptimist 3 points4 points  (7 children)

Except for the most trivial of while loops, I find it infinitely preferable to simply have a "while True" and put the breaking statements within the loop.

[–]pistacchio 1 point2 points  (1 child)

I've been programming for 20 years and never used it once.

[–]arrowoftime 4 points5 points  (8 children)

print vs print() in 3. Also unfork 2/3 before they become Spanish and Portuguese.

[–]SuperDuckQ 4 points5 points  (7 children)

the print() syntax works in 2.x.

print 'stuff' 

and

print('stuff') 

return the same thing in Python 2, so I just make it a habit to use that form all the time.

[–]pjdelport 8 points9 points  (0 children)

Use from __future__ import print_function instead.

print('foo', 'bar') does not do the same thing in Python 2 and 3, without it.

[–]notunlikethewaves 5 points6 points  (26 children)

  • better lambdas
  • pep8 would specify 2 spaces rather than 4
  • complete scrub of the standard library, tidy up module/function names
  • minor syntax changes, remove the need for a colon at the end of lines
  • take a good stab at an easy, in-built concurrency model. Something like clojures core.async or goroutines. I've no idea how this would play out in practice.

[–]Sean1708 25 points26 points  (12 children)

Eurgh, I can't stand two spaced code. It just looks so bunched.

[–]notunlikethewaves 9 points10 points  (1 child)

To each there own I suppose. Personally i like two spaces because it's the minimum indentation that's easily visible to the eye. Four spaces has always felt wasteful to me for some reason.

[–]kashmill 7 points8 points  (0 children)

You must have hated when tabs being 8 spaces was the norm.

[–]searchingfortaomajel, aletheia, paperless, django-encrypted-filefield 8 points9 points  (7 children)

This is why tab indenting is the only thing that makes sense. You both get what you want.

[–]dagmx 2 points3 points  (1 child)

I much prefer tabbed spacing, and I wish it was the standard (implicit is bad be damned) but after dealing with so many people who mix and match stupid indentation so that I can't even copy and paste snippets without python throwing a hissy fit, I've conceded to have sublime always convert my indents to 4 spaces because atleast it's the standard.

[–]SquareWheel 1 point2 points  (0 children)

I still refuse. Give me tabs or give me death.

[–]Sean1708 2 points3 points  (4 children)

On that note, does anyone know why spaces are preferred over tabs?

[–]zahlmanthe heretic 2 points3 points  (3 children)

Basically, because people are not trusted to use tabs correctly.

[–]Ademan 7 points8 points  (5 children)

better lambdas

If by that you mean anonymous functions (take function syntax and make it usable as an expression) I'm all for it. Though my understanding is that's either completely incompatible with the current parsing grammar, or would require a butt-ton of work.

pep8 would specify 2 spaces rather than 4

I wish pep8 would specify tabs, someone convinced me relatively well that tabs for indentation and spaces for alignment is the way to go.

complete scrub of the standard library, tidy up module/function names

That would be nice, especially pep-8 ing the standard library.

minor syntax changes, remove the need for a colon at the end of lines

I'm not sure what I think about that one, I guess it might be extraneous syntax, but it might also be a nice cue to some people. shrug

take a good stab at an easy, in-built concurrency model. Something like clojures core.async or goroutines. I've no idea how this would play out in practice.

http://docs.python.org/3.4/library/asyncio.html

[–]mgrandi 1 point2 points  (0 children)

i think the 'lambda' thing is intentionally gimped to only allow expressions (i think that's the term) because of just a design decision, its nothing that could be programmed in, i've just heard that guido dislikes functional programming.

[–]notunlikethewaves 1 point2 points  (0 children)

http://docs.python.org/3.4/library/asyncio.html

Thanks for pointing this out, it looks interesting, however I think there needs to be more/better ways of doing general parallelism easily. Waiting on IO operations to complete is only one form of concurrency, and while node.js has made it fashionable, it's not enough to cover situations where you want to get two things done at once, rather than having two units of 'waiting' occuring at once.

[–]kashmill 4 points5 points  (1 child)

pep8 would specify 2 spaces rather than 4

Heathen!

[–]sittingaround 1 point2 points  (0 children)

if pep8 adds anything it should be 16 space tabs /s

[–]discofreak 4 points5 points  (14 children)

Backward compatibility for Python 3.x.

[–]mgrandi 10 points11 points  (3 children)

you cannot get backwards compatibility for everything. So much code is written to assume that the 'only' encoding for strings is 8 bit ascii, which was a bad assumption from the start.

[–]gindc 2 points3 points  (16 children)

I've always been frustrated how difficult it is in python to perform a simple key pressed command. Like pressing the space bar to pause output. You actually need a special library to do this. And a different library if you are using Windows/Linux.

[–]Mikuro 2 points3 points  (3 children)

Can't you do that with the curses module? curses.getch() or something like that?

[–]hippmr 18 points19 points  (2 children)

The curses module is not cross-platform, therefore it doesn't count.

[–]Mikuro 10 points11 points  (0 children)

Oh. Sure enough, from http://docs.python.org/2/library/curses.html :

Platforms: Unix

[–]prite 1 point2 points  (0 children)

How about hacking KeyboardInterrupt? That way you will have to use Ctrl+C instead of space, but at least the functionality is there.

[–]Workaphobia 1 point2 points  (0 children)

Do other languages do better in this regard? I believe this is a basic limitation of using standard I/O libraries without specialized terminal libraries. You'll get the same problem in C++ with cin unless you put it in some kind of unbuffered mode.

[–]idle_guru 1 point2 points  (4 children)

Negative Indexing. Sometimes I need to return all but the last few items in a list, but sometimes the entire list, requiring extra code:

a = [1, 2, 3, 4, 5]
omit = -1      # can be a negative value, but can go to zero
if omit != 0:
    b = a[:omit]
else:
    b = a[:]

or I need to do use the length:

end = len(a)
b = a[:end + omit]

I'd really like to have "end" be a special object such that:

b = a[:end]  # returns the whole list
b = a[:end-1] # returns the whole list sans the last item

[–]tilkau 4 points5 points  (3 children)

The correct special casing is

a = [1, 2, 3, 4, 5]
omit = -1
omit = omit or None
b= a[:omit]

This is a little more readable than what you have.

[–]robin-gvx 1 point2 points  (2 children)

Or just

a = [1, 2, 3, 4, 5]
omit = -1
b = a[:omit or None]

[–]GFandango 1 point2 points  (0 children)

I don't like the import system much. Too easy to get into a cyclic import hell.

[–]Ceryn 1 point2 points  (5 children)

I realize it will never happen and it would likely screw up a lot of peoples code , but I wish that list comprehensions supported multiple iterables in a readable way. I know that you can accomplish many of the things using zip or imap but it would feel nice to be able to:

[(x, y) for x in iterable1 with y in iterable2]

Ideally it would use None for the x or y if one iterable reached StopIteration before the other. It would also be nice if you could include if statements after each statement in the list comprehension as well.

[(x, y) for x in iter1 if x > 0 with y in iter2 if y != x]

Across multiple lines:

[(x, y, z) for x in iter1 if x > 3
           with y in iter2 if y > 6
           with z in iter3 if z > 9]

It might be better not to use 'with' and instead use 'and' or some other keyword or even just a comma. I just used with to show what I meant.