squirrel
squirrel

Reputation: 1

Overwrite a function in a python library

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

Answers (2)

Alexey S. Larionov
Alexey S. Larionov

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

Floh
Floh

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

Related Questions