Your try block for importing reduce is unnecessary. In Python 2, it is still in the functools module, but it is also in the __builtin__ module.
You have a typo in your description. It should be 'contents', not 'contense'.
Since ASCII is a Python3-only flag, you might want to account for that in get_args(). It really isn't very complicated. Just add:
if args['ascii']:
try:
re.ASCII
except AttributeError:
parser.error("--ascii is compatible with Python 3 only")
I think get_args() is fine in how much it does. A regex of th(kl is invalid. Invalid arguments should be caught in the function that gets the arguments. I would, however, add a function that determines if a given regex is found in a file. That way get_files() could look like this:
def get_files(path, regex):
return (name
for root, dirs, files in os.walk(path)
for name in files
if file_matches(file, regex)
)
From How do I re.search or re.match on a whole file without reading it all into memory?How do I re.search or re.match on a whole file without reading it all into memory?, you can use mmap.mmap to save on memory usage. Note that Python 3 requires a bytes regex when using that function.