I have a module module containing 2 functions a and b splited into 2 different files m1.py and m2.py.
The module's file tree:
module/
__init__.py
m1.py
m2.py
__init__.py contains:
from .m1 import a
from .m2 import b
m1.py contains:
def a():
print('a')
m2.py contains:
from . import a
def b():
a()
Now, I want to override the function a in a main.py file, such that the function b uses the new function a. I tried the following:
import module
module.a = lambda: print('c')
module.b()
But it doesn't work, module.b() still print a.
I found a solution, that consists in not importing with from . import a but with import module.
m2.py becomes:
import module
def b():
module.a()
Related
I have multiple python scripts, like this:
utils.py
module1.py
module2.py
module3.py
main.py
...
In utils.py:
import some_lib
role_id = "some_key_1"
secret_id = "some_key_2"
def initialize():
real_key = some_web_request(role_id, secret_id)
some_lib.init(real_key)
# define some other functions using some_lib
In module1.py, module2.py, module3.py:
import utils
# define some other functions using functions in utils.py
In main.py:
import module1
import module2
import module3
# do something
I want to run utils.initialize() only once for initializing some_lib. However, due to how import works in python, if I put initialize() on global area in utils.py then it will run on every import statement run.
I can implement this like this, in utils.py
import some_lib
initialized = False
def initialize():
# same as above
if not initialized:
initialize()
initialized = True
Is this a good practice? Is there better or elegant way to implement this?
I'm trying to create an object from a custom class with a decorator in it.
Then I need to use the decorator of that object to create a bunch of functions in a different file.
I found the solution of using builtins online but it feels a bit hacky and makes my lsp spit out a bunch of errors.
I'm wondering if anyone knows a better solution.
This is my file structure:
main.py
mylib
├── A.py
└── B.py
main.py
import builtins
from mylib.A import A
a = A("This is printing in the decorator")
builtins.FOO = a
import mylib.B as B
B.foo()
B.poo()
A.py
class A:
def __init__(self, _message):
self.message = _message
def our_decorator(self, func):
def function_wrapper():
print(self.message)
func()
return function_wrapper
B.py
import builtins
#builtins.FOO.our_decorator
def foo():
print("foo")
#builtins.FOO.our_decorator
def poo():
print("poo")
I don't want to change the file structure if it can be avoided.
Using builtins to have a magically created decorator is indeed hacky.
An alternative would be to patch the functions in B from main. It is slightly cleaner (and linters should not complain) because the B module has no longer to be aware of the decorator:
main.py:
from mylib.A import A
a = A()
import mylib.B as B
# decorate here the functions of the B module
B.foo = a.our_decorator(B.foo)
B.poo = a.our_decorator(B.poo)
B.foo()
B.poo()
A.py is unchanged...
B.py:
def foo():
print("foo")
def poo():
print("poo")
As only one version of a module exists in a process, you can even use the functions of B from a third module, provided:
either it is imported after the decoration
or it only imports the module name (import mylib.B as B) and not directly the functions (from mylib.B import foo)
I have 2 Python modules (e.g. A.py & B.py) that have the same function names (the implementation is different though). A third module (C.py) has a function that requires the functions in A or B, depending on user choice.
A fourth module (D.py) will import either A or B, and then C.
How do I correctly setup the modules and imports?
# module A.py
def write():
print('A')
# module B.py
def write():
print('B')
# module C.py
def foo():
write()
# module D.py (main executed module)
if choiceA:
import A
import C
else:
import B
import C
C.foo()
This is essentially a basic case of a Strategy Pattern. Instead of doing a double-import and implicitly expecting module C to get the right module, you should just explicitly pass the appropriate selection for it to call.
Using modules A and B as before:
# module C.py
def foo(writer):
writer.write()
# module D.py
import A
import B
import C
if choiceA:
my_writer = A
elif choiceB:
my_writer = B
C.foo(my_writer)
This will also continue to work exactly the same way if you choose to define A, B, and C as a class hierarchy instead of modules.
Not much really.
Module A.py:
def write():
print('A')
Module B.py
def write():
print('B')
Module C.py
def foo(choice):
if choice == 'A':
import A
A.write()
elif choice == 'b':
import B
B.write()
else:
#whatever
module D.py
choice = input('Enter choice: ')
import C
C.foo(choice)
I have three python files:
a.py
theVariable = "Hello!"
b.py
import a
a.theVariable = "Change"
c.py
import a
while True:
print(a.theVariable)
I want c.py to print out "Change" instead of "Hello!". How can I do this and why wont this work?
There needs to be separate files because b.py would be running a Tkinter gui.
You can use classes to get an instance variable which holds some state
a.py
class Foo():
def __init__(self):
self.greeting = "Hello"
And create functions so that you can defer actions on references
b.py
def changer(f):
f.greeting = "Change"
When you import a class and then pass it to a function, you are passing a reference to something that can change state
c.py
from a import Foo
from b import changer
a = Foo()
for x in range(10): # simple example
if x > 5:
changer(a)
print(a.greeting)
a.py
theVariable = "Hello!"
def change(variable):
theVariable = variable
b.py
import a
change('change')
c.py
import a
while True:
print(theVariable)
i've been working with PyQt recently and this worked fine. setting a function in the orgin .py file makes it much simpler.
Given the folder structure as follows:
folder1
__init.py__
python1.py
folder2
__init.py__
class1.py
say in class1.py I have
class aa:
def __init__(self,max):
self.max=max
def hello(self):
print(self.max)
What should I import from python1.py to invoke aa.hello()?
i.e., in python1.py
#what do I need to import here
myaa=aa(100)
myaa.hello()
Answer my own:
from folder2.class1 import aa