You can call a function transparently within a mapping, thus ignoring
mode changes (e.g. by pressing :
), by using <expr>
mappings, like you suggested. Just use them to call a function like so:
fun! SetOpFunc()
set opfunc=CountSpaces
return 'g@'
endfun
nno <silent> <expr> <F4> SetOpFunc()