|
|
lexical
# introduces a comment for the rest of the line.
Names are case sensitive.
|
objects
x = expr # assignment, serves for definition
In addition to variables, lists are mutable.
x is y, x is not y
id(object)
copy.copy(object) (shallow copy)
|
generic expressions
( )
str(<expression>)
|
definitions
See assignment of objects. Gotcha: can be captured by a definition in an outer scope.
See functions.
|
functions
lambda arg: expr
foo(x)
def foo(x):
... x ...
return ... x ...
Note: None value is returned from functions by default.
def multi(x,y) : ...
multi(s,42)
Note: Multiple and variable args are not tuples.
|
sentences
not x, x and y, x or y
|
ordering
x<y, x<=y, x>y, x>=y, x==y, x!=y, x<>y
|
actions
for key in table.keys():
... # Indent rest of statement.
...
while expr:
...
if expr:
...
elif expr:
...
else:
...
foo # Line terminated
print expr
action1 ; action2
action3
pass # do nothing
|
numbers
0, 1, -1, ...
1.0, 2.0, 1.5, 0.6666, ...
x+y, x-y, x*y, x/y, x**y
x//y # floor division
abs(x), sin(x)
|
trivialities
None # type is None
None type is product of 0 types (like Haskell ())
|
sequences
thelist[3]
thelist[3:5] # has length 2, yay!
x in s, x not in s
s + t
len(s)
() (1,) (1,2) (1,2,3) ... # tuples
|
strings
Strings are sequences.
'stuff'
"backslash \\, newline \n, tab \t"
|
gotchas
Creation of variables is implicit.
Local variables in Python are (by definition!)
those variables to which a value is assigned in a function body
(and that aren't explicitly declared global).
Adding an assignment statement within a function body will change the meaning of
a reference to a global variable.
The use of global to prevent creation of a
variable is counterintuitive, compared to Perl's my ,
and it does not generalize to provide functionality that is
occasionally needed in nested scopes. As PEP 227 says,
The lack of
declarations and the inability to rebind names in enclosing scopes
are unusual for lexically scoped languages.
Functions are sort of first class. But can't be
defined in a function, to refer to local variables,
unless you use a future statement
from __future__ import nested_scopes
Even with the fix, to assign to a name in a containing scope you
must use a global declaration (a hassle at the point
of reference), and there's no way to assign to a name
in a containing function scope.
The / operator returns different results for
1.0/2.0 vs. 1/2 even though the operands are essentially
the same in Python. Unless you do
from __future__ import division
Expressions and statements are distinguished syntactically,
but not in meaning. Thus, there are two forms of function definition.
For another example, it's awkward when you
need if-then-else within an expression.
It's hard to write generic code involving sequences because,
although the access operators are consistent, the synthesis
operators vary, depending on whether you have a list, a tuple,
or a string.
In Python vs. Scheme by Moshe Zadka indicates some plusses for Scheme, incuding:
- Scheme supports proper closures, with lexical scoping.
Python's new scoping supports closures, but remains flawed.
- Any function can be defined anonymously, using lambda,
which I believe still is not possible with Python.
But can any function be defined at all in Python, i.e.
can you nest a def function in a function?
- Easy to code without side effects. I perceive this to be that
standard features don't give enough help to a functional style.
- No tail recursion optimization means that looping constructs
are required in efficient code.
Python variables/objects/references aren't first class values, i.e. if you try to pass
a variable as an argument, instead the value is used to
initialize a new variable. See this.
Since assignment and argument passing
have the same semantics, they are similarly flawed.
|
lists
Lists are sequences.
[] [1] [1,2] ...
|
|