       (goto-char start)
       (error "Enclosing block not found"))))
 
-(defun beginning-of-python-def-or-class (&optional class)
-  "Move point to start of def (or class, with prefix arg).
+(defun py-beginning-of-def-or-class (&optional class count)
+  "Move point to start of `def' or `class'.
 
 Searches back for the closest preceding `def'.  If you supply a prefix
-arg, looks for a `class' instead.  The docs assume the `def' case;
-just substitute `class' for `def' for the other case.
-
-If point is in a def statement already, and after the `d', simply
+arg, looks for a `class' instead.  The docs below assume the `def'
+case; just substitute `class' for `def' for the other case.
+
+When second optional argument is given programmatically, move to the
+COUNTth start of `def'.
+
+If point is in a `def' statement already, and after the `d', simply
 moves point to the start of the statement.
 
-Else (point is not in a def statement, or at or before the `d' of a
-def statement), searches for the closest preceding def statement, and
-leaves point at its start.  If no such statement can be found, leaves
-point at the start of the buffer.
-
-Returns t iff a def statement is found by these rules.
+Otherwise (i.e. when point is not in a `def' statement, or at or
+before the `d' of a `def' statement), searches for the closest
+preceding `def' statement, and leaves point at its start.  If no such
+statement can be found, leaves point at the start of the buffer.
+
+Returns t iff a `def' statement is found by these rules.
 
 Note that doing this command repeatedly will take you closer to the
 start of the buffer each time.
 
-If you want to mark the current def/class, see
-`\\[py-mark-def-or-class]'."
+If you want to mark the current `def', see `\\[py-mark-def-or-class]'."
   (interactive "P")			; raw prefix arg
+  (if (not count)
+      (setq count 1))
   (let ((at-or-before-p (<= (current-column) (current-indentation)))
-	(start-of-line (progn (beginning-of-line) (point)))
-	(start-of-stmt (progn (py-goto-initial-line) (point))))
-    (if (or (/= start-of-stmt start-of-line)
-	    (not at-or-before-p))
-	(end-of-line))			; OK to match on this line
-    (re-search-backward (if class "^[ \t]*class\\>" "^[ \t]*def\\>")
-			nil 'move)))
-
-(defun end-of-python-def-or-class (&optional class)
-  "Move point beyond end of def (or class, with prefix arg) body.
-
-By default, looks for an appropriate `def'.  If you supply a prefix arg,
-looks for a `class' instead.  The docs assume the `def' case; just
-substitute `class' for `def' for the other case.
-
-If point is in a def statement already, this is the def we use.
-
-Else if the def found by `\\[beginning-of-python-def-or-class]'
-contains the statement you started on, that's the def we use.
-
-Else we search forward for the closest following def, and use that.
-
-If a def can be found by these rules, point is moved to the start of
-the line immediately following the def block, and the position of the
-start of the def is returned.
+	(start-of-line (goto-char (py-point 'bol)))
+	(start-of-stmt (goto-char (py-point 'bos)))
+	(start-re (if class
+		      "^[ \t]*class\\>"
+		    "^[ \t]*def\\>"))
+	)
+    ;; searching backward
+    (if (and (< 0 count)
+	     (or (/= start-of-stmt start-of-line)
+		 (not at-or-before-p)))
+	(end-of-line))
+    ;; search forward
+    (if (and (> 0 count)
+	     (zerop (current-column))
+	     (looking-at start-re))
+	(end-of-line))
+    (re-search-backward start-re nil 'move count)
+    (goto-char (match-beginning 0))))
+
+;; Backwards compatibility
+(defalias 'beginning-of-python-def-or-class 'py-beginning-of-def-or-class)
+
+(defun py-end-of-def-or-class (&optional class count)
+  "Move point beyond end of `def' or `class' body.
+
+By default, looks for an appropriate `def'.  If you supply a prefix
+arg, looks for a `class' instead.  The docs below assume the `def'
+case; just substitute `class' for `def' for the other case.
+
+When second optional argument is given programmatically, move to the
+COUNTth end of `def'.
+
+If point is in a `def' statement already, this is the `def' we use.
+
+Else, if the `def' found by `\\[py-beginning-of-def-or-class]'
+contains the statement you started on, that's the `def' we use.
+
+Otherwise, we search forward for the closest following `def', and use that.
+
+If a `def' can be found by these rules, point is moved to the start of
+the line immediately following the `def' block, and the position of the
+start of the `def' is returned.
 
 Else point is moved to the end of the buffer, and nil is returned.
 
 Note that doing this command repeatedly will take you closer to the
 end of the buffer each time.
 
-If you want to mark the current def/class, see
-`\\[py-mark-def-or-class]'."
+If you want to mark the current `def', see `\\[py-mark-def-or-class]'."
   (interactive "P")			; raw prefix arg
+  (if (and count (/= count 1))
+      (py-beginning-of-def-or-class (- 1 count)))
   (let ((start (progn (py-goto-initial-line) (point)))
 	(which (if class "class" "def"))
 	(state 'not-found))
     ;; move point to start of appropriate def/class
     (if (looking-at (concat "[ \t]*" which "\\>")) ; already on one
 	(setq state 'at-beginning)
-      ;; else see if beginning-of-python-def-or-class hits container
-      (if (and (beginning-of-python-def-or-class class)
+      ;; else see if py-beginning-of-def-or-class hits container
+      (if (and (py-beginning-of-def-or-class class)
 	       (progn (py-goto-beyond-block)
 		      (> (point) start)))
 	  (setq state 'at-end)

  (define-key py-mode-map "\C-c#"     'py-comment-region)
  (define-key py-mode-map "\C-c?"     'py-describe-mode)
  (define-key py-mode-map "\C-c\C-hm" 'py-describe-mode)
  (define-key py-mode-map "\e\C-a"    'beginning-of-python-def-or-class)
  (define-key py-mode-map "\e\C-e"    'end-of-python-def-or-class)
  (define-key py-mode-map "\C-c-"     'py-up-exception)
  (define-key py-mode-map "\C-c="     'py-down-exception)
  ;; information

  ;; bol  -- beginning of line
  ;; eol  -- end of line
  ;; bod  -- beginning of defun
  ;; bob  -- beginning of buffer
  ;; eob  -- end of buffer
  ;; boi  -- back to indentation
  ;; bos  -- beginning of statement
  ;; 
  ;; This function does not modify point or mark.
  (let ((here (point)))
    (cond
     ((eq position 'bol) (beginning-of-line))
     ((eq position 'eol) (end-of-line))
     ((eq position 'bod) (py-beginning-of-def-or-class))
     ;; Kind of funny, I know, but useful for py-up-exception.
     ((eq position 'bob) (beginning-of-buffer))
     ((eq position 'eob) (end-of-buffer))
     ((eq position 'boi) (back-to-indentation))
     ((eq position 'bos) (py-goto-initial-line))
     (t (error "unknown buffer position requested: %s" position))
     )
    (prog1
