Re: Passing information between modules

2022-11-21 Thread Barry


> On 21 Nov 2022, at 21:23, r...@zedat.fu-berlin.de wrote:
> 
> dn  writes:
>> 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.
> 
>  I had many different functions that are supposed to take
>  a "context" argument. If I would make them all methods of
>  a class with a "context" field, that would be a huge class
>  containing methods with many different purposes, which
>  reminds of the "anti pattern" "God class".

Do you haves lots of free standing functions? Are all these functions
not part of classes?

> 
>> 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!
> 
>  Yes, but my problem was not so much with setting up the env,
>  but with passing it to many library functions.

Are you writing procedural code or object oriented? Why do you have so
many functions outside of a small number of classes?

> 
>> Is this how you implement?
> 
>  I'm not sure whether I understand the meaning of this question.

You appear not to be doing object oriented design.

> 
>  My library had a "console context" (before I started to use
>  the Python logging facility instead). That console context was
>  the default for output of progress and error messages.
> 
>  A client had the possibility to call functions with a custom
>  context, and then the function would use this custom context
>  for progress and error messages. The custom context could
>  direct those message to a text field in a GUI, for example. 
> 
>  Instead of passing this custom context to many library
>  functions, it might be simpler to "pass it to the library
>  once". This could be done via:
> 
> import library
> library.context = my_GUI_context

That is not oo design. I get the feeling that you need a better understanding
of how to structure a non-trivia library.

If you need the context object then you must pass it around.

> 
>  , but I wonder whether this "writing into another module"
>  is really possible in every Python implementation and whether
>  it will still be supported in the future. I do not see such
>  a pattern being used with the standard packages and suppose
>  that there might be a reason for this!
> 
>  The same question applies to the more advanced technique of
>  using "importlib.util.find_spec", "importlib.util.module_from_spec",
>  and ".__spec__.loader.exec_module" to even support having
>  different instances of a single module with different globals.
> 
>  I can now formulate my question this way:
> 
>  Many functions of a library have in their source code calls
>  like "PRINT( f'Done. Output was written to {filename}.' )".
>  The library uses "print" as a default for "PRINT", but
>  should explicitly support clients substituting a custom
>  implementation to be used for "PRINT". What's the best way
>  for the client to "pass" his custom implementation to the
>  library (which is a package or a module)?

Each place you have PRINT you need to have context.print calls.
You said above that you have, or had, such an object - pass it around and use 
it.

If passing it around is the problem then you need to look at why you code
has that problem.

Barry

> 
> 
> -- 
> https://mail.python.org/mailman/listinfo/python-list
> 

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-21 Thread Thomas Passin

On 11/21/2022 12:24 AM, dn wrote:

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?".


This can happen today if, for example, a class is changed to use slots 
for everything.  Between slots and type checking, it can become 
impossible to add an arbitrary attribute.  *You* may be able to avoid 
this, but if you use someone else's modules or classes it could happen 
at any time.


I might regret the loss of being able to assign an arbitrary attribute 
wherever I like, but for complex libraries, it is probably a good idea 
in the long run.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread Chris Angelico
On Mon, 21 Nov 2022 at 16:26, dn  wrote:
> Am put-off by the 'smell' of subverting/adapting names like print() =
> surprise/confusion factor - but I think I understand where you're going.

To be fair, redefining the "print" function IS one of the reasons that
it's no longer a statement. Though I would generally recommend
maintaining its signature and purpose.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread dn

On 21/11/2022 01.29, Stefan Ram wrote:

dn  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


Re: Passing information between modules

2022-11-20 Thread Thomas Passin

On 11/21/2022 12:01 AM, dn wrote:

On 21/11/2022 12.07, Dan Kolis wrote:
If you understand its meaning, it achieves my purpose. If you don't I 
you're perhaps not a programmer...


Ouch!

Does the first sentence imply who is the more important person in the 
interaction? Does the second further the idea that anyone/everyone who 
is not at your 'level' has no worth?



Folks, this is getting into ad hominem territory.  I suggest it's time 
to end the thread, since it's no longer productive.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread dn

On 21/11/2022 12.07, Dan Kolis wrote:

If you understand its meaning, it achieves my purpose. If you don't I you're 
perhaps not a programmer...


Ouch!

Does the first sentence imply who is the more important person in the 
interaction? Does the second further the idea that anyone/everyone who 
is not at your 'level' has no worth?


--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread Thomas Passin

On 11/20/2022 4:07 PM, Roel Schroeven wrote:

Thomas Passin schreef op 20/11/2022 om 20:33:

https://devblogs.microsoft.com/oldnewthing/20050607-00/?p=35413
https://devblogs.microsoft.com/oldnewthing/20101125-00/?p=12203

Now that I think about it, The Old New Thing is also where I got the 
global vs local thing: "Don’t use global state to manage a local 
problem", https://devblogs.microsoft.com/oldnewthing/20081211-00/?p=19873




Bingo!
--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread Dan Kolis
Its advice, I don't think the style issue is particularly important.

If you understand its meaning, it achieves my purpose. If you don't I you're 
perhaps not a programmer...

I like the abruptness of technical writing as a style, actually. If that is how 
machine learning ( aka 'A.I.' ) tends to compose messages, this seems mostly 
compatible with the sorts of written material I both make and consume.

 
https://interestingliterature.com/2017/03/10-of-the-best-poems-about-forests-and-trees/

The whisper of the aspens is not drowned,
And over lightless pane and footless road,
Empty as sky, with every other sound
Not ceasing, calls their ghosts from their abode,

there's one for you... a click will get you nine more. but none will help you 
write a better, more maintainable program.

Regards,
Dan
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread Chris Angelico
On Mon, 21 Nov 2022 at 09:37, Dan Kolis  wrote:
>
> Using sys.stdout / is simply nonsense. The more I think about it, the more I 
> realise how bad it is.
>
> Going on about it endlessly seems pointless.
>
> If the even mini threading thing is turned on, now what ? some other module 
> eats the message intended for a different module ? A state machine with its 
> own matching code in sends and receives to reuse the unwanted singular value ?
>
> The precise rules for establishing a variable without the global keyword is 
> not obvious, or catcat of anything  by leaving a empty set dangling initially.
>
> *especially* if the program is fundamentally open ended, that is, there could 
> be considerable new functions sharing ideas all over, planning ahead for as 
> good 45 seconds is a lot better then endless hacking any old way.

You should print this out and get it on a t-shirt. It's a perfect
example of AI-generated text.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread Dan Kolis
Using sys.stdout / is simply nonsense. The more I think about it, the more I 
realise how bad it is.

Going on about it endlessly seems pointless.

If the even mini threading thing is turned on, now what ? some other module 
eats the message intended for a different module ? A state machine with its own 
matching code in sends and receives to reuse the unwanted singular value ?

The precise rules for establishing a variable without the global keyword is not 
obvious, or catcat of anything  by leaving a empty set dangling initially.

*especially* if the program is fundamentally open ended, that is, there could 
be considerable new functions sharing ideas all over, planning ahead for as 
good 45 seconds is a lot better then endless hacking any old way.

1) Make a variable in a module known to be a shared item. Named for that 
specifically.
def Mt() {}
IoDot = {} # Once before program does anything... in global. ref import global 
as gi later.

2) Create highly generalised speculative named ideas init each variable once 
with a {}
ioDot.weights = Mt{} ; ( I make it a local method so the method can stand alone 
for unit testing )

3) Uniformly ref it with a import statement. in all 'other' modules

4) When a shared idea is apparent concat a new named portion to the name for 
this purpose. Then use those fairly without fussing as required. If one scares 
you, set it to {} after some scary moment if you are feeling fussy.

5) All 'ideas' will be at a 3rd or more subsid level in naming. ex:

gi.IoDot.weights.trucks = whatever
gi.IoDot.weights.cars = whatever

gi.toastDot.warnings.tooHeavy
gi.toastDot.warnings.isOk

These can all be any kind of object. So easy

I have a very sizable highly generalized program using this and have not found 
any defect in doing so.

Regs
Dan

 

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread Roel Schroeven

Thomas Passin schreef op 20/11/2022 om 20:33:

https://devblogs.microsoft.com/oldnewthing/20050607-00/?p=35413
https://devblogs.microsoft.com/oldnewthing/20101125-00/?p=12203

Now that I think about it, The Old New Thing is also where I got the 
global vs local thing: "Don’t use global state to manage a local 
problem", https://devblogs.microsoft.com/oldnewthing/20081211-00/?p=19873


--
"In the old days, writers used to sit in front of a typewriter and stare out of
the window. Nowadays, because of the marvels of convergent technology, the thing
you type on and the window you stare out of are now the same thing.”
-- Douglas Adams

--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread Thomas Passin

On 11/20/2022 1:50 PM, Roel Schroeven wrote:

Stefan Ram schreef op 20/11/2022 om 11:39:

   The idea is about parameterizing the behavior of a module.
   For example, the module "M" may contain functions that contain
   "input.read()" to get input and "output.write()" to write
   output. Then one would write code like (the following is
   not correct Python code, just pseudo code assuming a possible
   extended Python where one can assigned to a module before
   it's loaded):

import sys

M.input = sys.stdin
M.output = sys.stdout
import M

   . So now M would use sys.stdin for input and sys.stdout
   for output.
I feel this is a bad idea. This uses global state for customizing local 
behavior. Yes, maybe you want to customize behavior in one of your 
modules, or even only in some functions, or maybe in several or even all 
of your modules. But by changing module "M", you're changing it for 
*every* user of it, even for standard library modules or third party 
packages. You can't customize it in different ways in different parts of 
your code. And it's a kind of spooky action at a distance: the behavior 
of a module gets changed by another, possibly completely unrelated, 
module. This has the potential to grossly violate the principle of least 
surprise.

   If someone else would ask this, I'd tell him to use a class:

import MM
import sys

M = MM.moduleclass( input=sys.stdin, output=sys.stdout )
That is a *much* better solution, and I would even say it's the only 
acceptable solution.

   , but this is another layer of indirection, so it's a bit
   more complicated than the direct approach of parameterizing
   a module.

I'm not even sure it's more complicated. It's more explicit, which I like.

You could have a hybrid approach, like what the random module does. The 
functions in the random module are actually methods of a global hidden 
instance of class random.Random; if you want random generators with 
separate states you can create your own instance(s) of random.Random, or 
of random.SystemRandom.



As I wrote, it's another case of "what if everyone did this". e.g.:

https://devblogs.microsoft.com/oldnewthing/20050607-00/?p=35413
https://devblogs.microsoft.com/oldnewthing/20101125-00/?p=12203

--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread dn

On 21/11/2022 01.03, Stefan Ram wrote:

dn  writes:

In some respects we have the (OP) problem because Python does not have
"interfaces" as a formal component of the language.


   What one can do today is,

class my_interface( metaclass=abc.ABCMeta ):
 """This interface ..."""

 @abc.abstractmethod
 def method( __self__, *s, **x ):
 """This abstract method ..."""

# ...

my_interface.register( my_class )

# ...



Ugh!

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread Roel Schroeven

Stefan Ram schreef op 20/11/2022 om 11:39:

   The idea is about parameterizing the behavior of a module.
   For example, the module "M" may contain functions that contain
   "input.read()" to get input and "output.write()" to write
   output. Then one would write code like (the following is
   not correct Python code, just pseudo code assuming a possible
   extended Python where one can assigned to a module before
   it's loaded):

import sys

M.input = sys.stdin
M.output = sys.stdout
import M

   . So now M would use sys.stdin for input and sys.stdout
   for output.
I feel this is a bad idea. This uses global state for customizing local 
behavior. Yes, maybe you want to customize behavior in one of your 
modules, or even only in some functions, or maybe in several or even all 
of your modules. But by changing module "M", you're changing it for 
*every* user of it, even for standard library modules or third party 
packages. You can't customize it in different ways in different parts of 
your code. And it's a kind of spooky action at a distance: the behavior 
of a module gets changed by another, possibly completely unrelated, 
module. This has the potential to grossly violate the principle of least 
surprise.

   If someone else would ask this, I'd tell him to use a class:

import MM
import sys

M = MM.moduleclass( input=sys.stdin, output=sys.stdout )
That is a *much* better solution, and I would even say it's the only 
acceptable solution.

   , but this is another layer of indirection, so it's a bit
   more complicated than the direct approach of parameterizing
   a module.

I'm not even sure it's more complicated. It's more explicit, which I like.

You could have a hybrid approach, like what the random module does. The 
functions in the random module are actually methods of a global hidden 
instance of class random.Random; if you want random generators with 
separate states you can create your own instance(s) of random.Random, or 
of random.SystemRandom.


--
"You can fool some of the people all the time, and all of the people some
of the time, but you cannot fool all of the people all of the time."
-- Abraham Lincoln
"You can fool too many of the people too much of the time."
-- James Thurber

--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread Dan Kolis


It's certainly not an "incredibly bad idea", it is a mildly bad idea however. 
Why be stuck with maybe's and just text strings ?

Functions as "first class operators" and object oriented languages are a 
natural pair with a bit of heavy thinking.

The problem is... there is nobody giving you a 3 line solution without 
thinking. Its a 7 line solution requiring understanding. One you do it right, 
then its a 2 line solution !

Once you construct the bridges; then, in any module you can consider global 
sharables like so:

First vague use of functionality 
  gi.setAsideArea.NewIdea = 'ok'

Next usages anywhere !
  gi.setAsideArea.NewIdea = "StateMachine Argon"

There is no hangover of vague ideas bothering future executions of the code 
either. This is not some scary file buried in a directory system which needs 
calling and might be stale, using bad ideas, etc.

 How much easier can a solution be ?

 Regards,
Daniel B. Kolis
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-20 Thread Avi Gross
There is no guarantee that argv is consulted earlier in the program than
other modules will use it for communication.

Consider a case where a program does look at argv but later wants to call
another program using some or all of the components of argv and now there
are added components there. That could lead to all kinds of problems.

Some languages have global objects available that you can add to, sort of
like a dictionary object and as long as you add keys guaranteed  to be
unique,  can be used carefully to coordinate between parts of your program.
Of course, you may also need to use techniques that ensure atomic
concurrency.

Reusing argv is a hack that should not be needed.


On Sat, Nov 19, 2022, 4:37 PM Thomas Passin  wrote:

> On 11/19/2022 4:28 PM, Thomas Passin wrote:
> > On 11/19/2022 3:46 PM, Michael F. Stemper wrote:
> >> On 18/11/2022 04.53, Stefan Ram wrote:
> >>>Can I use "sys.argv" to pass information between modules
> >>>as follows?
> >>>
> >>>in module A:
> >>>
> >>> import sys
> >>> sys.argv.append( "Hi there!" )
> >>>
> >>>in module B:
> >>>
> >>> import sys
> >>> message = sys.argv[ -1 ]
> >>
> >> I just tried and it appears that one can append to sys.argv. However,
> >> it seems like an incredibly bad idea.
> >
> > For that matter, you can just directly add attributes to the sys module,
> > no need to use sys.argv:
> >
> >  >>> import sys
> >  >>> sys._extra = 'spam'   # Not an exception
> >  >>> print(sys._extra)
> > spam
> >
> > Probably not the best idea, though.  Better to use some module that you
> > control directly.
>
> This could be one of those things of which Raymond Chen (The Old New
> Thing) asks "what if everyone did this?".  Imagine if every
> (non-standard-library) module misused sys or sys.argv like this.  The
> result could be chaotic.
>
> Best to put all your own stuff into modules that you yourself control.
>
> --
> https://mail.python.org/mailman/listinfo/python-list
>
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-19 Thread Dan Kolis


In a module mostly for this purpose; ( big program means many modules aka files 
):
--
globalIdeas.py
--
# Empty object maker ( M T ) ... get it say it !
class MT():
pass

# IO dot area readier 
def prepIO():

# Prep for general IO use really
dotObjOps.ioSupport = MT()
dotObjOps.ioSupport.sequenceMacro = MT()


-
In Every use module:
-
import globalIdeas as   gi 

so now without burdensome advanced planning, a swap area is not only segregated 
by function
but doesn't overly pollute too much globalism everywhere.

New Idea:
gl.ioSupport.sequencesMacro.newStartupIdea = {}
gl.ioSupport.sequencesMacro.thingToReuse = 14
etc ...

A method in globalIdeas is named like startEverything():
  prepIO()
  prepNext()
  prepSounds()
   etc...

This seems to me amenable to management of large programs in which absolutely 
any shaped objects be created as needed and be RW sharable in orderly fashion, 
etc.

Its important if you read write files to plan ahead and have MT() names in 
surplus before you need them.

I cant see any drawback to this at all. Many program have very legit reasons to 
have universal ideas. This avoids the emotional burden of the' "global KW" ; 
entirely.

Regards,
Daniel B. Kolis









-- 
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-19 Thread Cameron Simpson

On 18Nov2022 10:53, Stefan Ram  wrote:

 Can I use "sys.argv" to pass information between modules
 as follows? [...]


Stefan, it looks like most of the replies take the form: yes you can do 
that but it is probably a bad idea.


Could you outline the larger situation where  you want to do this? Often 
this kind of response ("yes but don't!") can be a clue that you're 
chasing the wrong (sorry, "suboptimal/poor") solution to a problem which 
can be solved in another way.


Cheers,
Cameron Simpson 
--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-19 Thread Thomas Passin

On 11/19/2022 3:46 PM, Michael F. Stemper wrote:

On 18/11/2022 04.53, Stefan Ram wrote:

   Can I use "sys.argv" to pass information between modules
   as follows?

   in module A:

import sys
sys.argv.append( "Hi there!" )

   in module B:

import sys
message = sys.argv[ -1 ]


I just tried and it appears that one can append to sys.argv. However,
it seems like an incredibly bad idea.


For that matter, you can just directly add attributes to the sys module, 
no need to use sys.argv:


>>> import sys
>>> sys._extra = 'spam'   # Not an exception
>>> print(sys._extra)
spam

Probably not the best idea, though.  Better to use some module that you 
control directly.



--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-19 Thread Thomas Passin

On 11/19/2022 4:28 PM, Thomas Passin wrote:

On 11/19/2022 3:46 PM, Michael F. Stemper wrote:

On 18/11/2022 04.53, Stefan Ram wrote:

   Can I use "sys.argv" to pass information between modules
   as follows?

   in module A:

import sys
sys.argv.append( "Hi there!" )

   in module B:

import sys
message = sys.argv[ -1 ]


I just tried and it appears that one can append to sys.argv. However,
it seems like an incredibly bad idea.


For that matter, you can just directly add attributes to the sys module, 
no need to use sys.argv:


 >>> import sys
 >>> sys._extra = 'spam'   # Not an exception
 >>> print(sys._extra)
spam

Probably not the best idea, though.  Better to use some module that you 
control directly.


This could be one of those things of which Raymond Chen (The Old New 
Thing) asks "what if everyone did this?".  Imagine if every 
(non-standard-library) module misused sys or sys.argv like this.  The 
result could be chaotic.


Best to put all your own stuff into modules that you yourself control.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-19 Thread Michael F. Stemper

On 18/11/2022 04.53, Stefan Ram wrote:

   Can I use "sys.argv" to pass information between modules
   as follows?

   in module A:

import sys
sys.argv.append( "Hi there!" )

   in module B:

import sys
message = sys.argv[ -1 ]


I just tried and it appears that one can append to sys.argv. However,
it seems like an incredibly bad idea.

--
Michael F. Stemper
The name of the story is "A Sound of Thunder".
It was written by Ray Bradbury. You're welcome.
--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-19 Thread dn

On 18/11/2022 23.53, Stefan Ram wrote:

   Can I use "sys.argv" to pass information between modules
   as follows?

   in module A:

import sys
sys.argv.append( "Hi there!" )

   in module B:

import sys
message = sys.argv[ -1 ]

   . "sys.argv" is said to be a list by the standard
   documentation, so it should be guaranteed to be
   appendable as lists are appendable.

   Moreover, in my own program, after its startup, third parties
   do not inspect "sys.argv". So by appending something to it
   (or modifying it) I do not tamper with information that might
   be misinterpreted by any third party outside of my own code.

   Another hack might be:

   in module A

import builtins
builtins.message = "Hi there!"

   in module B

import builtins
message = builtins.message

   But I'm not sure whether modules (such as "builtins" here)
   are guaranteed to be modifyable and visible by the language
   reference in this way though



The re-use of built-in features is risky, if only because of the remote 
possibility that a future version of Python will add something that 
clashes. That's why Python makes such good (and careful) use of namespaces!


In some respects we have the (OP) problem because Python does not have 
"interfaces" as a formal component of the language. So, we often 
get-away with taking an easier course - but in doing-so, may forget that 
they serve specific purposes.



There is a general idea that globals are harmful, a code-smell, etc; and 
therefore something to be avoided. However, the global namespace is a 
(built-in!) feature of Python, so why not use it?


The problem comes when we try to re-use module A or B in some other 
application. It may not be relatively-obvious that some global, eg 
config, must be previously-defined and made-available. If you're 
prepared to accept that risk - and presumably combat the criticism by 
carefully (and prominently) documenting it, just as with any other 
docstring, where's the problem? (caveat emptor!)



Considering the use-case, it is unlikely to be as trivial as the 
example-given (OP). A classic example would be set of credentials to 
access an RDBMS and specific table(s).


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").


Thereafter, when needing such data within a module, calling the 
particular function/class/method by name (moduleNM.function(...) ), and 
passing only that section of the env[ironment] required. Such achieved 
by passing some sub-structure of env, or by passing a retrieval/get method.
(a module handling GUI, for example, has no business looking at 
RDBMS-creds - which it would be able to do if the whole env was passed!)



but...

the module's code will expect its data in a particular form (an 
interface!), which must be documented and understood by both the 
provider and consumer (people and software)


- which sounds like the same 'solution' to the 'globals problem'...

--
Regards,
=dn
--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-18 Thread Axy via Python-list

On 18/11/2022 10:53, Stefan Ram wrote:

   Can I use "sys.argv" to pass information between modules
   as follows?

   in module A:

import sys
sys.argv.append( "Hi there!" )

   in module B:

import sys
message = sys.argv[ -1 ]


This idea has a couple of flaws so can be regarded as bad.

However, if nothing else works (including suggested globals.py module), 
then os.environ could be a better way.


Axy.

--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-18 Thread Thomas Passin

On 11/18/2022 10:19 AM, Tobiah wrote:

On 11/18/22 02:53, Stefan Ram wrote:

   Can I use "sys.argv" to pass information between modules
   as follows?

   in module A:

import sys
sys.argv.append( "Hi there!" )

   in module B:

import sys
message = sys.argv[ -1 ]


Kind of seems like a code smell.  I think you would normally
just inject the dependencies like:

 module_b.do_thing("Hi there!")

If you really want to have a module-global space,
you could just create a module globals.py, and
import that in every module that needs to share globals.
You can just do globals.message = "Hi there!" and
from another module do print globals.message.


The module can even create the message or variable dynamically.  I have 
one that, when it is loaded, asks git for the branch and changeset hash 
the code's working directory is using.  This module is imported by 
others that use the branch and changeset data in one way or another.


--
https://mail.python.org/mailman/listinfo/python-list


Re: Passing information between modules

2022-11-18 Thread Tobiah

On 11/18/22 02:53, Stefan Ram wrote:

   Can I use "sys.argv" to pass information between modules
   as follows?

   in module A:

import sys
sys.argv.append( "Hi there!" )

   in module B:

import sys
message = sys.argv[ -1 ]


Kind of seems like a code smell.  I think you would normally
just inject the dependencies like:

module_b.do_thing("Hi there!")

If you really want to have a module-global space,
you could just create a module globals.py, and
import that in every module that needs to share globals.
You can just do globals.message = "Hi there!" and
from another module do print globals.message.






--
https://mail.python.org/mailman/listinfo/python-list