Passing information between modules

dn PythonList at DancesWithMice.info
Mon Nov 21 00:24:41 EST 2022


On 21/11/2022 01.29, Stefan Ram wrote:
> dn <PythonList at DancesWithMice.info> writes:
>> A 'standard' solution is to collect all such configuration-data at the
>> start of the application, into an object (or other data-structure) - I
>> usually call it "env" (an instantiation of "Environment").
> 
>    Yeah, I had some functions of my library take such an "env",
>    which in my library is called "context":
> 
> def python_version_check( major=3, minor=9, context=x_default_context ):
>      passed = _sys.version_info >=( major, minor )
>      if not passed:
>           requirements_info = "This program requires Python " + \
>                               str( major ) + "." + str( minor )+ "+.\n"
>           version_info = "Currently running under Python {}.{}.\n". \
>                          format( *_sys.version_info[ :2 ] )
>           context.warning( requirements_info + version_info )
>      return passed
> 
>    . But so far I am using "context" only for logging, so I am
>    now thinking about replacing with Pythons logging facility.
> 
>    One possible application of "context", however, would also be
>    normal output, which has to be shown to the user, not only
>    logging as in:
> 
> def show_sum( x, y, context=x_default_context ):
>    context.print( f'The sum is {x+y}.' )
> 
>    . For example, there could by a "GUI context" by which
>    "context.print" would append the output to some GUI text
>    field. Using the logging facility to output text that must
>    be show to the user, would abuse logging somewhat.
> 
> def show_sum( x, y, context=x_default_context ):
>    logger.log\
>    ( my_custom_level_for_output_to_user, f'The sum is {x+y}.' )
> 
>    Or one could "print patch" a module, via (using the class from
>    a recent post of mine):
> 
> M = prepare_module( 'M' )
> M.print = my_gui_print_function
> M = M.load()
> M.f()
> 
>    and "show_sum" would be simply:
> 
> def show_sum( x, y, context=x_default_context ):
>    print( f'The sum is {x+y}.').
> 
>    My original question probably was intended to be something
>    like: "Today, we can add attributes to a module from the
>    outside. How large is the risk that this will be forbidden
>    one day, so that all code using this will stop working?".


Am put-off by the 'smell' of subverting/adapting names like print() = 
surprise/confusion factor - but I think I understand where you're going.

What about an ABC which is inherited by two classes. One class handles 
all the detail of output to GUI. The other, similarly, output to the 
terminal, log, (whatever). The ABC should require an output() method, 
with suitable signature. The two classes will vary on the fine detail of 
the HOW, leaving the calling-routine to produce the WHAT.

Now, at the config stage, take the instructions to define whichever the 
user prefers, and instantiate that class. Then the 'calling-routine' can 
use the instantiated object as an interface to whichever type of output.

If the choices on-offer include not just either/or, but also 'both of 
the above'. The instantiation would need to be a class which called both 
class's output() method serially.


Your use of the word "context" provoked some thought. (you don't know 
just how dangerous that could become!)

In many ways, and as described, an Environment/context class could be 
very easily coded with formal __enter__() and __exit__() methods. The 
mainline might then become:

with Environment() as env:
     # processing

There would be no need to explicitly prevent any 'processing' if the 
set-up doesn't work, because that context manager class will handle it all!

NB haven't had time to try this as a refactoring exercise.

Is this how you implement?

-- 
Regards,
=dn


More information about the Python-list mailing list