ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
#!/usr/bin/python
#Sharing variables between functions demo
#Function one
def one():
a = 5
b = 2
c = a * b
return a, b, c
#Function two
def two():
d = 1
e = 2
f = 3
return d, e, f
#Function three
def three():
g = 10
h = 20
i = 30
return g, h, i
#Function four
def four():
a = 'Cow'
b = 'Horse'
c = 'Sheep'
return a, b, c
#Print returns from functions
print('Returns from functions:')
print('Return from one =', one())
print('Return from two =', two())
print('Return from three =', three())
print('Return from three =', four())
print('')
#Math with vars from different functions
print('Math with variables from different functions:')
print('one.c * two.f =', one()[2] * two()[2])
print('three.i / three.g =', three()[2] / three()[0])
print('three.g + two.e =', three()[0] + two()[1])
print('((three.i + one.b) - two.f) =', (three()[2] + one()[1]) - two()[2])
print('')
#!/usr/bin/python
m = 'Hello there'
def one():
global a
a = 'cow'
b = 5
return a, b
def two():
c = a
d = 'horse'
return c, d
def three():
e = a
print(e)
print(m)
one()
print(two())
three()
I can't tell what you are doing. You are going to have to give some better info.
If you need a module in every python script then you'll have to import it. If that is what you are doing though, fix your code. Python is slow enough to start with.
i know i can use log importing config.logger in any package/module.
log, however, is a variable which is going to be be used in pretty much all of the packages and modules of the application, and if the application grows i would like to do it without importing config.logger again and again.
i hope the question is clearer and not too silly...
i know i can use log importing config.logger in any package/module.
log, however, is a variable which is going to be be used in pretty much all of the packages and modules of the application, and if the application grows i would like to do it without importing config.logger again and again.
i hope the question is clearer and not too silly...
what we have here is a global name in a module namespace that is initialized by a statement in the module. subsequent imports of log from config.logger will not re-execute the initialization of log (or anything in the already initialized module namespace [✪]), so go ahead and add the statement in whatever subpackages/modules need log etc just as if you were declaring any other variable you need:
Code:
from config.logger import log
[✪]
Quote:
Originally Posted by docs.python.org/3/tutorial/modules.html#more-on-modules
A module can contain executable statements as well as function definitions. These statements are intended to initialize the module. They are executed only the first time the module name is encountered in an import statement. 1 (They are also run if the file is executed as a script.)
1 In fact function definitions are also ‘statements’ that are ‘executed’; the execution of a module-level function definition enters the function name in the module’s global symbol table.
✪✪python docs tl;dr: everything in the module is interpreted ONCE
You can confirm this for yourself by writing something to standard out inside of config_logger() and see it will only execute once to form log (e.g. from main but not again when importing demo_module.py).
krunch3r
~~~~~~~~~~~~~~~~~~~~~~~
i krunch therefore i am
thank you very much for your time and your patience, now it's much clearer to me.
Quote:
You can confirm this for yourself by writing something to standard out inside of config_logger() and see it will only execute once to form log (e.g. from main but not again when importing demo_module.py).
that's indeed what i did yesterday after my last post and that test led me to the same conclusion as yours.
there's still a small drawback with this design, however: what if such an ubiquitous module needs refactoring? let's say in a couple of years i want to change the module's name from logger.py to logging.py, or change the name of its parent folder. at that point the app might contain dozens of modules and i should edit the import statement in each of them... i could use a sed command for that, but it would leave me a little bit scared...
thank you very much for your time and your patience, now it's much clearer to me.
that's indeed what i did yesterday after my last post and that test led me to the same conclusion as yours.
there's still a small drawback with this design, however: what if such an ubiquitous module needs refactoring? let's say in a couple of years i want to change the module's name from logger.py to logging.py, or change the name of its parent folder. at that point the app might contain dozens of modules and i should edit the import statement in each of them... i could use a sed command for that, but it would leave me a little bit scared...
tl;dr:
to have flexibility in changing package path and/or module name anywhere in the dev lifecycle you may consider these high-level solutions (incomplete) utilizing any combination of these standard modules (module names are underlined)
✬ sys.modules: add key of previously used package_path.module to sys.modules so that it points to the new package_path.module then import as either the old or the new
✬✬ builtins: add log to builtins namespace via dot notation and refer to log directly without dot notation (magick!)
✬✬✬ importlib: use lookup table (inside of __builtins__ or maybe os.environ) to lookup the package.module path (string) as an argument to importlib.import_module
✬if you change the name, you can make references to the imported module by adding a new key to the sys.modules dictionary so that the old name refers to the new name on subsequent imports [1]
Code:
#############
# main.py
import sys
import myconfig.logger # changed from config.logger
sys.modules['config.logger']=myconfig.logger
from my_module.my_module import my_func
########################
# my_module/my_func.py
from config.logger import log
def my_func():
# use log here
✬✬but you sound like a hacker and who has "outgrown" the sandbox 😋 so you could add log (or perhaps more sanely a lookup table) to the universally "exported" namespace __builtins__ via the builtins module [2,3]
Code:
# main.py
import config.logger
import builtins
builtins.log=config.logger.log
from my_module.my_module import my_func
my_func() # my_func() can refer to log directly without importing it
the above will draw criticism for polluting the builtin namespace but it does demonstrate global in the sense you appear to be thinking of.
you would probably draw less fire if instead you define a lookup table in __builtins__ that contains current the module path then pass it as an argument to importlib.import_modules [4]
✬✬✬
Code:
#./main.py
import os
import builtins
import myconfig.logger
builtins.mymodules=dict()
# builtins.mymodules['config.logger']=config.logger # config.logger not an existing package.module path
builtins.mymodules['config.logger']=myconfig.logger NOTE: this is stringified later for importlib.import_module
from my_module.my_module import my_func
my_func()
# ---------------------
###########################
#./my_module/my_module.py
import importlib
log = importlib.import_module(mymodules['config.logger'].__name__).log
if you use importlib and a lookup table, you could also use os.environ to store keys so as to not pollute __builtins__.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.