With erikstokes' answer, I was able to write this, which uses python.el to narrow to the outermost scope regardless of where point is in the class:
(defun my/python-narrow-to-outer-scope ()
(interactive)
(save-excursion
(python-nav-beginning-of-block)
(let ((last-point nil))
(while (or (null last-point) (/= (point) last-point))
(setq last-point (point))
(python-nav-backward-up-list)))
(forward-line)
(narrow-to-defun)))
Or more specifically narrowing to the 'nearest' opening class definition (nearest moving up the hierarchy of class/def nesting from point):
(defun my/py-statement-opens-base (regexp)
(let ((orig (point))
erg)
(save-excursion
(back-to-indentation)
(python-nav-forward-statement)
(python-nav-backward-statement)
(when (and
(<= (line-beginning-position) orig)(looking-back "^[ \t]*" (line-beginning-position))(looking-at regexp))
(setq erg (point))))
(when (called-interactively-p 'any) (message "%s" erg))
erg))
(defconst my/py-class-re "[ \t]*\\_<\\(class\\)\\_>[ \n\t]"
"Matches the beginning of a class definition. ")
(defun my/py-statement-opens-class-p ()
"Return `t' if the statement opens a functions or class definition, nil otherwise. "
(my/py-statement-opens-base my/py-class-re))
(defun my/python-narrow-to-class ()
(interactive)
(save-excursion
(python-nav-beginning-of-block)
(while (not (my/py-statement-opens-class-p))
(python-nav-backward-up-list))
(forward-line)
(narrow-to-defun)))