Avoiding namespace pollution in python by using Classes -
a bit of background
i'm writing python module own use, , i'm using python's logging
module. there handlers , formatters , pair of functions create (for part) won't used anywhere else. however, still want able access , modify these variables elsewhere (for instance, other closely-coupled modules or scripts)
a simple namespace
what i'm doing using class definition group of variables together, this:
class _logging: '''a little namespace our logging facilities. don't try instantiate it: group logging objects , keep them out of global namespace''' global logger def __init__(self): raise typeerror("that's not how works...") def gz_log_rotator(source, dest): '''accept source filename , destination filename. copy source dest , add gzip compression. use logging.handlers.rotatingfilehandler.rotator.''' gzip.open(dest, 'wb', 1) ofile, open(source, 'rb') ifile: ofile.write(ifile.read()) os.remove(source) def gz_log_namer(name): '''accept filename, , return ".gz" appended. use logging.handlers.rotatingfilehandler.namer.''' return name + ".gz" fmtr = logging.formatter( '[%(asctime)s:%(name)s:%(thread)05d:%(levelname)-8s] %(message)s') gz_rotfile_loghandler = logging.handlers.rotatingfilehandler( '%s.log' % __name__, mode='a', maxbytes=(1024**2 * 20), backupcount=3) gz_rotfile_loghandler.setlevel(5) gz_rotfile_loghandler.setformatter(fmtr) gz_rotfile_loghandler.rotator = gz_log_rotator gz_rotfile_loghandler.namer = gz_log_namer simplefile_loghandler = logging.filehandler( '%s.simple.log' % __name__, mode='w') simplefile_loghandler.setlevel(15) simplefile_loghandler.setformatter(fmtr) stream_loghandler = logging.streamhandler() stream_loghandler.setlevel(25) stream_loghandler.setformatter(fmtr) logger = logging.getlogger(__name__) logger.setlevel(5) logger.addhandler(gz_rotfile_loghandler) logger.addhandler(simplefile_loghandler) logger.addhandler(stream_loghandler)
however, pylint complains (and agree) methods defined in class should either static methods, or follow naming conventions first parameters (e.g. gz_log_rotator(self, dest)
), not how function used, , more confusing.
fun fact
during process i've discovered instances of classmethod
, staticmethod
not in , of callable (???). while method defined in class namespace callable both within , without, classmethods
, staticmethods
callable when accessed through class (at point refer underlying function, not classmethod
/staticmethod
object)
>>> class thing: ... global one_, two_, three_ ... def one(self): ... print('one') ... @classmethod ... def two(cls): ... print('two') ... @staticmethod ... def three(): ... print('three') ... one_, two_, three_ = one, two, 3 ... >>> thing.one() traceback (most recent call last): file "<stdin>", line 1, in <module> typeerror: one() missing 1 required positional argument: 'self' >>> thing.two() 2 >>> thing.three() 3 >>> # expected >>> one_() traceback (most recent call last): file "<stdin>", line 1, in <module> typeerror: one() missing 1 required positional argument: 'self' >>> # far >>> two_() traceback (most recent call last): file "<stdin>", line 1, in <module> typeerror: 'classmethod' object not callable >>> # what? >>> three_() traceback (most recent call last): file "<stdin>", line 1, in <module> typeerror: 'staticmethod' object not callable >>> # ???
my question
is there better way hold these variables without polluting namespace?
the code have works correctly, makes me feel little unclean. define function called once , call it, either lose references don't return, or i'm polluting global namespace. make _hidden
, feel should logically grouped. make _logging
bona fide class, put of stuff in __init__
function , tack little variables onto self
, feels inelegant. create file this, far i've gotten held in same file. other option seemed palatable make 2 functions staticmethods
, refer them through our class (i.e. _logging.gz_log_namer
), seem impossible.
>>> class thing: ... @staticmethod ... def say_hello(): ... print('hello!') ... thing.say_hello() ... traceback (most recent call last): file "<stdin>", line 1, in <module> file "<stdin>", line 5, in thing attributeerror: type object 'thing' has no attribute 'say_hello' >>>
as stands, best option see use selfless methods.
Comments
Post a Comment