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 ]
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.
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 ]
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
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 ]
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:
spamimport sys
sys._extra = 'spam' # Not an exception
print(sys._extra)
Probably not the best idea, though. Better to use some module that you control directly.
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.
spamimport sys
sys._extra = 'spam' # Not an exception
print(sys._extra)
Can I use "sys.argv" to pass information between modules
as follows? [...]
On 18Nov2022 10:53, Stefan Ram <[email protected]> wrote:
Can I use "sys.argv" to pass information between modulesStefan, it looks like most of the replies take the form: yes you can do
as follows? [...]
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
In some respects we have the (OP) problem because Python does not have >"interfaces" as a formal component of the language.
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").
M = prepare_module( 'M' )
M.a = 20221120
M = M.load()
M.f()
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:
spamimport sys
sys._extra = 'spam' # Not an exception
print(sys._extra)
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
The idea is about parameterizing the behavior of a module.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
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.
If someone else would ask this, I'd tell him to use a class:That is a *much* better solution, and I would even say it's the only
import MM
import sys
M = MM.moduleclass( input=sys.stdin, output=sys.stdout )
, but this is another layer of indirection, so it's a bitI'm not even sure it's more complicated. It's more explicit, which I like.
more complicated than the direct approach of parameterizing
a module.
dn <[email protected]> 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 )
# ...
Stefan Ram schreef op 20/11/2022 om 11:39:
The idea is about parameterizing the behavior of a module.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
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.
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:That is a *much* better solution, and I would even say it's the only acceptable solution.
import MM
import sys
M = MM.moduleclass( input=sys.stdin, output=sys.stdout )
, but this is another layer of indirection, so it's a bitI'm not even sure it's more complicated. It's more explicit, which I like.
more complicated than the direct approach of parameterizing
a module.
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 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.
Roel Schroeven <[email protected]> writes:
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, orThis seems to be similar to functions like "forward" of the
of random.SystemRandom.
module "turtle". I believe the global function "forward" is
actually calling the method "forward" of a special turtle,
but one still can create more turtles.
https://devblogs.microsoft.com/oldnewthing/20050607-00/?p=35413 https://devblogs.microsoft.com/oldnewthing/20101125-00/?p=12203
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.
Thomas Passin schreef op 20/11/2022 om 20:33:
https://devblogs.microsoft.com/oldnewthing/20050607-00/?p=35413Now that I think about it, The Old New Thing is also where I got the
https://devblogs.microsoft.com/oldnewthing/20101125-00/?p=12203
global vs local thing: "Don’t use global state to manage a local
problem", https://devblogs.microsoft.com/oldnewthing/20081211-00/?p=19873
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?
If you understand its meaning, it achieves my purpose. If you don't I you're perhaps not a programmer...
dn <[email protected]> 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.
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.
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!
Is this how you implement?
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?".
On 21 Nov 2022, at 21:23, [email protected] wrote:
dn <[email protected]> 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".
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.
Is this how you implement?
I'm not sure whether I understand the meaning of this question.
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
, 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)?
--
https://mail.python.org/mailman/listinfo/python-list
| Sysop: | Keyop |
|---|---|
| Location: | Huddersfield, West Yorkshire, UK |
| Users: | 715 |
| Nodes: | 16 (2 / 14) |
| Uptime: | 21:50:56 |
| Calls: | 12,104 |
| Calls today: | 4 |
| Files: | 15,004 |
| Messages: | 6,518,114 |