Reputation: 1
I want to overwrite a function in a python library. Example: This is my library, already compiled, in example.py
def my_function():
return "Hello World"
if __name__ == "__main__":
return my_function()
Of course if I run example.py it prints "Hello World".
What I want to do is to be able to overwrite my_function()
in terms to return another stuff (Example "Hello ...") and be able to run example.py and print "Hello ..."
I need that because I want to deliver a library used by my users in which they can customize some code, like in the example. How can I do it ?
---EDIT--- The users will not touch the "main" in example.py.
in the example.py I call my_function() but I want to overwrite my_function() in the example.py in the user code.
Upvotes: 0
Views: 2259
Reputation: 7927
I'm sure there can be some hack to do this with functions, but better to use Object-Oriented-Programming style to support this functionality in an understandable way. You can define a class containing your functions, and users can override some functions by inheriting this class and implmenting their own variants of the functions:
# my_library.py
class LibraryFunctionality:
def my_function():
return "My function"
def my_other_function():
return "My other function"
then users could do
# user.py
import my_library
class MyFunctionality(LibraryFunctionality):
def my_function():
return "My unique function"
MyFunctionality.my_function() # returns "My unique function"
MyFunctionality.my_other_function() # returns "My other function"
If you have a large method, that you want to let users to override by parts (without requiring them to repeat the same implementation), you can use a "Template method" design pattern, where you split a big method into many functions for all the steps, and then users can override some steps selectively. For example something as big as this:
# my_library.py
class LibraryFunctionality:
def before_initialization_step():
pass
def initialization_step():
return "My"
def after_initialization_step(state):
return state
def before_work_step(state):
return state
def work_step(state):
return state + " function"
def after_work_step(state):
return state
def before_return_step(state):
return state
def return_step(state):
return state
def my_function():
LibraryFunctionality.before_initialization_step()
state = LibraryFunctionality.initialization_step()
state = LibraryFunctionality.after_initialization_step(state)
state = LibraryFunctionality.before_work_step(state)
state = LibraryFunctionality.work_step(state)
state = LibraryFunctionality.after_work_step(state)
state = LibraryFunctionality.before_return_step(state)
return LibraryFunctionality.return_step(state)
Then users can override specific steps as I've already shown:
# user.py
import my_library
class MyFunctionality(LibraryFunctionality):
def before_work_step(state):
return state + " unique"
LibraryFunctionality.my_function() # returns "My function"
MyFunctionality.my_function() # returns "My unique function"
Upvotes: 1
Reputation: 909
When your users will import the module they will do:
import the_module
to use your function then they would do
the_module.my_function()
This is technically possible to do something like
import the_module
def replacement():
print("something else")
the_module.my_function = replacement
But I don’t see any added value here between this and them just creating the function themselves.
Where it can come with value, it is in OOP, where then you will create a class with a set of given method, and one can inherit your class and override some methods, still keeping others.
class Animal:
def say(self):
print("something")
def sleep(self):
print("sleeping")
class Cat(Animal):
def say(self):
print("Miaou")
Upvotes: 3