Class CatalogWalker can walk thru a list of catalogs, calculate and report some statistics Just for review and may be useful for somebody

from os import walk
from time import time

from abc import ABCMeta, abstractmethod

class Reporter(object):
    __metaclass__=ABCMeta

    @abstractmethod
    def report(self, catalogs_cntr, files_ctnr, speed):
        """ output catalogs_cntr, files_ctnr, speed to somewhere """
        #pass

class ConsoleIndicator(Reporter):
    def __init__(self, out_splitter):
        self.__out_splitter=out_splitter

    def report(self, catalogs_cntr, files_ctnr, speed):
        if self.__out_splitter and self.__out_splitter.pipes:
            _result = "\rcataloges:" + repr(catalogs_cntr).rjust(8) 
            _result += "\tfiles:" + repr(files_ctnr).rjust(13) 
            _result += "\tspeed: %12.3f"%speed + " files/s"

            self.__out_splitter.write(_result)
            self.__out_splitter.flush()        

class CatalogsWalker(object):
    """ """

    def __init__(self, catalogs, reporter=None):
        """ """

        self.__files_cntr, self.__catalogs_cntr, self.__start_time, self.__speed = 0, 0, 0, 0
        self.__reporter = reporter 
        self.__catalogs = catalogs if hasattr(catalogs, "__iter__") else [catalogs]

    def __iter__(self):
        self.__files_cntr, self.__catalogs_cntr, self.__start_time, self.__speed = 0, 0, 0, 0
        self.__start_time=time()
        for catalog in self.__catalogs:
            for p,d,ns in walk(catalog): 
                _ = d;
                self.__catalogs_cntr+=1
                for n in ns:
                    self.__files_cntr+=1
                    self.__speed=self.__files_cntr/(time()-self.__start_time)
                    if self.__reporter:
                        self.__reporter.report(self.__catalogs_cntr, self.__files_cntr, self.__speed)
                    yield p,n

    @property
    def reporter(self):
        return self.__reporter

    @property
    def catalog_counter(self):
        return self.__catalogs_cntr    

    @property
    def file_counter(self):
        return self.__files_cntr

    @property
    def start_time(self):
        return self.__start_time

    @property
    def speed(self):
        return self.__speed
Docstrings

I'm not a big fan of the empty-docstring fakeout """ """. It would be really useful to see some actual documentation of what this is for and how to use it.



Names

You have a lot of underscores. Per the style guide:


  Generally, double leading underscores should be used only to avoid name conflicts with attributes in classes designed to be subclassed.


Given that you use the unmangled names as properties, this is clearly not the case; you should use a single underscore to indicate private by convention.

I certainly wouldn't prepend an underscore on local names (e.g. _result), as they can't be accessed from outside the method anyway.

You have a few too-short names, too; p? d? ns? n? Your code would be much more readable with more meaningful names.



Strings

I would have written e.g. 

_result = "\rcataloges:" + repr(catalogs_cntr).rjust(8) 


as

result = '\rcataloges:{!r:&gt;8}'.format(catalogs_cntr)


and I definitely wouldn't mix and match; why:

_result += "\tspeed: %12.3f"%speed + " files/s"


rather than 

_result += "\tspeed: %12.3f files/s" % speed


You could also consider building a list of elements, then joining them together; this makes it easier to add, rearrange and remove fields or change the separator:

result = []
result.append("cataloges:{!r:&gt;8}".format(catalogs_cntr))
result.append("files:{!r:&gt;13}".format(files_ctnr)) 
result.append("speed: {:12.3f} files/s".format(speed))
result = '\r' + '\t'.join(result)




Code

You have lines that are too long - you should limit to 80 characters. You can reduce this using Python's continuation, e.g.

self.__reporter.report(self.__catalogs_cntr, self.__files_cntr, self.__speed)


becomes

self.__reporter.report(self.__catalogs_cntr, 
                       self.__files_cntr, 
                       self.__speed)




This is particularly odd-looking:

for p,d,ns in walk(catalog): 
    _ = d;


The semi-colon ; is redundant, and you won't see it very often in Python code (except where trying to fit multiple statements on one line, which is rarely the right choice). If you aren't going to use d, don't assign it at all, and note the whitespace after commas:

for p, _, ns in walk(catalog):