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

Popular posts from this blog

Ansible - ERROR! the field 'hosts' is required but was not set -

customize file_field button ruby on rails -

SoapUI on windows 10 - high DPI/4K scaling issue -