On 21/11/2022 01.29, Stefan Ram wrote:
dn <pythonl...@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
--
https://mail.python.org/mailman/listinfo/python-list