What do you wish you'd known about when you started learning Python?

Question:

I’ve decided to learn Python 3. For those that have gone before, what did you find most useful along the way and wish you’d known about sooner?

Asked By: Undistraction

||

Answers:

  1. I wished I didn’t know Java.
  2. More functional programming. (see itertools module, list comprehension, map(), reduce() or filter())
Answered By: Alexandru

Most helpful: Dive Into Python. As a commenter points out, if you’re learning Python 3, Dive Into Python 3 is more applicable.

Known about sooner: virtualenv.

Answered By: Hank Gay

List comprehension (makes a list cleanly):

[x for x in y if x > z]

Generator expansion (same as list comprehension but doesn’t evaluate until it is used):

(x for x in y if x > z)
Answered By: Paul Tarjan

I really like list comprehension and all other semifunctional constructs. I wish I had known those when I was in my first Python project.

Answered By: lhahne

List comprehensions, if you’re coming to Python fresh (not from an earlier version).

Answered By: Justin R.

Don’t have variable names that are types. For example, don’t name a variable “file” or “dict”

Answered By: inspectorG4dget

Learn how to use iPython
It’s got Tab completion.
View all the elements in your namespace with ‘whos’.

After you import a module, it’s easy to view the code:

>>> import os
>>> os?? # this display the actual source of the method
>>> help() # Python's interactive help. Fantastic!

Most Python modules are well documented; in theory, you could learn iPython and the rest of what you’d need to know could be learned through the same tool.

iPython also has a debug mode, pdb().
Finally, you can even use iPython as a python enabled command line. The basic UNIX commands work as %magic methods. Any commands that aren’t magic command can be executed:

>>> os.system('cp file1 file2')
Answered By: BryanWheelock

I learned Python back before the 1.5.2 release, so the things that were key for me back then may not be the key things today.

That being said, a crucial thing that took me a little bit to realize, but I now consider crucial: much functionality that other languages would make intrinsic is actually made available by the standard library and the built-ins.

The language itself is small and simple, but until you’re familiar with the built-ins and the “core parts” of the standard library (e.g., nowadays, sys, itertools, collections, copy, …), you’ll be reinventing the wheel over and over. So, the more time you invest in getting familiar with those parts, the smoother your progress will be. Every time you have a task you want to do, that doesn’t seem to be directly supported by the language, first ask yourself: what built-ins or modules in the standard library will make the task much simpler, or even do it all for me? Sometimes there won’t be any, but more often than not you’ll find excellent solutions by proceeding with this mindset.

Answered By: Alex Martelli

Closures. Clean and concise, without having to resort to using a Strategy Pattern unlike languages such as Java

Answered By: Julson Lim

Two brain-cramping things. One of which doesn’t apply to Python 3.

a = 095

Doesn’t work. Why? The leading zero is an octal literal. The 9 is not valid in an octal literal.

def foo( bar=[] ):
    bar.append( 1 )
    return bar

Doesn’t work. Why? The mutable default object gets reused.

Answered By: S.Lott

Decorators. Writing your own is not something you might want to do right away, but knowing that @staticmethod and @classmethod are available from the beginning (and the difference between what they do) is a real plus.

Answered By: David Berger

What I really liked: List comprehensions, closures (and high-order functions), tuples, lambda functions, painless bignumbers.

What I wish I had known about sooner: The fact that using Python idioms in code (e.g. list comprehensions instead of loops over lists) was faster.

Answered By: MAK

If you learn from a good book, it will not only teach you the language, it will teach you the common idioms. The idioms are valuable.

For example, here is the standard idiom for initializing a class instance with a list:

class Foo(object):
    def __init__(self, lst=None):
        if lst is None:
            self.lst = []
        else:
            self.lst = lst

If you learn this as an idiom from a book, you don’t have to learn the hard way why this is the standard idiom. @S.Lott already explained this one: if you try to make the default initializer be an empty list, the empty list gets evaluated just once (at compile time) and every default-initialized instance of your class gets the same list instance, which was not what was intended here.

Some idioms protect you from non-intended effects; some help you get best performance out of the language; and some are just small points of style, which help other Python fans understand your code better.

I learned out of the book Learning Python and it introduced me to some of the idioms.

Here’s a web page devoted to idioms: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html

P.S. Python code that follows the best-practice Python idioms often is called “Pythonic” code.

Answered By: steveha

I wish I knew well a functional language. After playing a bit with Clojure, I realized that lots of Python’s functional ideas are borrowed from Lisp or other functional langs

Answered By: GabiMe

I implemented plenty of recursive directory walks by hand before I learned about os.walk()

Answered By: Dan Monego

That multi-core was the future. Still love Python. It’s writes a fair bit of my code for me.

Answered By: wheaties

I wish I’d known right off the bat how to code idiomatically in Python. You can pick up any language you like and start coding in it like it’s C, Java, etc. but ideally you’ll learn to code in “the spirit” of the language. Python is particularly relevant, as I think it has a definite style of its own.

While I found it a little later in my Python career than I would have liked, this excellent article wraps up many Python idioms and the little tricks that make it special. Several of the things people have mentioned in their answers so far are contained within:
Code Like a Pythonista: Idiomatic Python.

Enjoy!

Answered By: Matt Baker
  • What enumerate is for.
  • That seq = seq.append(item) and seq = seq.sort() both set seq to None.
  • Using set to remove duplicates.
  • Pretty much everything in the itertools and collections modules.
  • How the * and ** prefixes for function arguments work.
  • How default arguments to functions work internally (i.e. what f.func_defaults is).
  • How (why, really) to design functions so that they are useful in conjunction with map and zip.
  • The role of __dict__ in classes.
  • What import actually does.
Answered By: Robert Rossney
  • using help() in the shell on any object, class or path
  • you can run import code;
    code.interact(local=locals())
    anywhere in your code and it will start a python shell at that exact point
  • you can run python -i yourscript.py to start a shell at the end of yourscript.py
Answered By: ʞɔıu

One of the coolest things I learned about recently was the commands module:

>>> import commands
>>> commands.getoutput('uptime')
'18:24  up 10:22, 7 users, load averages: 0.37 0.45 0.41'

It’s like os.popen or os.system but without all of the DeprecationWarnings.

And let’s not forget PDB (Python Debugger):

% python -m pdb poop.py
Answered By: jathanism

Dropping into interactive mode in IPython

from IPython.Shell import IPShellEmbed
ipshell = IPShellEmbed()
ipshell()
Answered By: pufferfish

When I started with python, started out with main methods from the examples. This was because I didn’t know better, after that I found this on how to create a better main method.

Answered By: daramarak

That a tuple of a single item must end with a comma, or it won’t be interpreted as a tuple.

pprint() is very handy (yes, 2 p’s)

reload() is useful when you’re re-testing a module while making lots of rapid changes to a dependent module.

And learn as many common “idioms” as you can, otherwise you’ll bang your head looking for a better way to do something, when the idiom really is regarded as the best way (e.g. ugly expressions like ' '.join(), or the answer to why there is no isInt(string) function…. the answer is you can just wrap the usage of a “possible” integer with a try: and then catch the exception if it’s not a valid int. The solution works well, but it sounds like a terrible answer when you first encounter it, so you can waste a lot of time convincing yourself it really is a good approach.

Those are some things that wasted several hours of my time to determine that my first draft of some code which felt wrong, really was acceptable.

Readings from python.org:

http://wiki.python.org/moin/BeginnerErrorsWithPythonProgramming
http://wiki.python.org/moin/PythonWarts

Answered By: Kilo

Sequential imports overwrite:

If you import two files like this:

from foo import *
from bar import *

If both foo.py and bar.py have a function named fubar(), having imported the files this way, when you call fubar, fubar as defined in bar.py will be executed. The best way to avoid this is to do this:

import foo
import bar

and then call foo.fubar or bar.fubar. This way, you ALWAYS know which file’s definition of fubar will be executed.

Answered By: inspectorG4dget

Pretty printing:

>>> print "%s world" %('hello')
hello world

%s for string

%d for integer

%f for float

%.xf for exactly x many decimal places of a float. If the float has lesser decimals that indicated, then 0s are added

Answered By: inspectorG4dget

Maybe a touch more advanced, but I wish I’d known that you don’t use threads to take advantage of multiple cores in (C)python. You use the multiprocessing library.

Answered By: jcdyer

Tab completion and general readline support, including histories, even in the regular python shell.

$ cat ~/.pythonrc.py 
#!/usr/bin/env python

try:
    import readline
except ImportError:
    print("Module readline not available.")
else:
    import rlcompleter
    readline.parse_and_bind("tab: complete")

    import os
    histfile = os.path.join(os.environ["HOME"], ".pyhist")
    try:
        readline.read_history_file(histfile)
    except IOError:
        pass
    import atexit
    atexit.register(readline.write_history_file, histfile)
    del os, histfile

and then add a line to your .bashrc

export PYTHONSTARTUP=~/.pythonrc.py

These two things lead to an exploratory programming style of “it looks like this library might do what I want”, so then I fire up the python shell and then poke around using tab-completion and the help() command until I find what I need.

Generators and list comprehensions are more useful than you might think. Don’t just ignore them.

Answered By: Peter Boothe

Functional programming tools, like all and any

Answered By: inspectorG4dget
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.