The elisp code below provides some basic functionality for setting source block switches on a per-file basis with org-version 9.0.5.
You can set switches for all source blocks within a subtree with the switches
property. If switches
is set before the first heading it is valid for the whole file.
For an example the org-file
#+PROPERTY: switches: +n
* first level
#+BEGIN_SRC emacs-lisp
(message "block in first level")
#+END_SRC
** second level
#+BEGIN_SRC emacs-lisp
(message "block in second level")
(message "second line")
#+END_SRC
* second heading in the first level
#+BEGIN_SRC emacs-lisp
(message "first line")
(message "second line")
#+END_SRC
exports the following rendered html-output.

This is only a very basic implementation. A better implementation would require changes on the orgmode source code itself.
Since this feature is very reasonable I've filed an enhancement request at the orgmode mailing list.
(require 'cl-lib)
(require 'org)
(require 'ox)
(require 'org-element)
(defvar org-src-switch-alist nil
"Alist mapping an org source code switches to its argument parser (which can be nil) and its interpreter.")
(setq org-src-switches-alist
'(("-n" org-src-parse-number (lambda (num) (list :number-lines (cons 'new (or num 0)))))
("+n" org-src-parse-number (lambda (num) (list :number-lines (cons 'continued (or num 0)))))
("-r" nil (:retain-labels nil))
("-i" nil (:preserve-indent t))
("-l" org-src-parse-quoted-string (lambda (str) (assert (stringp str)) (list :label-fmt str)))
("-k" nil (:use-labels t))))
(defun org-src-parse-number ()
"Parse number at point and return it as the only element of a list.
If parsing fails the return value is (nil)."
(list
(when (looking-at "[0-9]")
(read (current-buffer)))))
(defun org-src-parse-quoted-string ()
"Parse quoted string at point and return it as the only element of a list.
If parsing fails the return value is (nil)."
(list
(when (looking-at "\"")
(read (current-buffer)))))
(defun org-src-switch-parse (str)
"Parse org mode source block switches in string STR."
(let ((sw-re (regexp-opt (mapcar 'car org-src-switches-alist)))
ret)
(with-temp-buffer
(insert str)
(goto-char (point-min))
(while (progn
(skip-syntax-forward " ")
(looking-at sw-re))
(goto-char (match-end 0))
(let* ((sw (assoc-string (match-string 0) org-src-switches-alist))
(parser (cadr sw))
(interpreter (nth 2 sw))
args)
(skip-syntax-forward " ")
(when parser
(setq args (funcall parser)))
(setq ret
(append
ret
(if (functionp interpreter)
(apply interpreter args)
interpreter))))))
ret))
(defun org-src-switch-propagate (keyword-element)
(let ((value
(and (string-equal (org-element-property :key keyword-element) "PROPERTY")
(org-element-property :value keyword-element))))
(when (and value (string-match "switches:" (downcase value)))
(setq value (org-src-switch-parse (substring value (match-end 0))))
(let ((parent (org-element-property :parent keyword-element)))
(when (and
(eq (org-element-type parent) 'section)
(eq (org-element-type (org-element-property :parent parent)) 'org-data))
(setq parent (org-element-property :parent parent)))
(org-element-map
parent
'(src-block example-block)
`(lambda (bl)
(cl-loop for pair on ',value by 'cddr
do (org-element-put-property bl (car pair) (cadr pair)))))))))
(defun org-element-parse-buffer-ad (info)
"Filter the INFO returned by `org-element-parse-buffer' for global switches
and apply them to source code blocks."
(org-element-map info 'keyword #'org-src-switch-propagate)
info)
(advice-add #'org-element-parse-buffer :filter-return #'org-element-parse-buffer-ad)