0

I am looking to essentially create a new method and replace the old method. All I am changing is the size of the range by 3 at the minimum and maximum.

The method in_range in the object power_spectrum in this library is

    def in_range(self, frequency_min, frequency_max):
        """Returns part of the power spectrum within a given frequency range."""
        ir = copy(self)
        mask = (self.frequency > frequency_min) & (self.frequency <= frequency_max)
        ir.frequency = self.frequency[mask]
        ir.power = self.power[mask]
        return irtype here

I wanted to increase the range by 3 on each side and replace the original method so I made a new method and tried to apply it to the object like below

    def in_range(self, frequency_min, frequency_max):
        
        ir = list.copy(self)
        mask = (self.frequency > frequency_min - 3) & (self.frequency <= frequency_max + 3)
        ir.frequency = self.frequency[mask]
        ir.power = self.power[mask]
        return ir

    power_spectrum.in_range = in_range

I got an error: plot_power_spectrum..in_range() missing 1 required positional argument: 'frequency_max'

Then checked the method with print(inspect.getsource(power_spectrum.in_range)) and it showed this.

    def in_range(self, frequency_min, frequency_max):
        """Returns part of the power spectrum within a given frequency range."""
        ir = copy(self)
        mask = (self.frequency > frequency_min) & (self.frequency <= frequency_max)
        ir.frequency = self.frequency[mask]
        ir.power = self.power[mask]
        return ir

    def in_range(self, frequency_min, frequency_max):
        
        ir = list.copy(self)
        mask = (self.frequency > frequency_min - 3) & (self.frequency <= frequency_max + 3)
        ir.frequency = self.frequency[mask]
        ir.power = self.power[mask]
        return ir

So it just added it to the end of the old method instead of replacing it which is not what I wanted to do.

  • Does this answer your question? [What is monkey patching?](https://stackoverflow.com/questions/5626193/what-is-monkey-patching) – JonSG Mar 03 '23 at 13:34

1 Answers1

0

You can replace items of a class by doing something like this

class X:
    def y(self):
        print("SOMETHING")
def z(self):
    print("SOMETHING ELSE")
X().y()
X.y = z #replacement done here
X().y()

You could also do this in cpython (not recommended, but possible)

X.y.__code__ = z.__code__

A more conventional thing to do would be

class X2(X):
    def y(self):
        print("SOMETHING ELSE")
X2().y()
arrmansa
  • 518
  • 10
  • While replacing the code object is possible, there are many things (default parameter values, closures, etc) that are stored directly in the function object, not in its `__code__` attribute. Unless you are willing to go into more depth on the topic, I would just not mention that option at all. – chepner Mar 03 '23 at 13:40
  • Forgive me for my ignorance if I miss understood your response. I am a PhD student trying to use python for the first time for data analysis. I am trying to adjust a method that is part of a script in a thrid party library that I am using. I tried your suggestion and it did not work. A friend of mine suggested adjusting the scripts directly in the library files which I tried but was unsuccessful as it seems to not recognize my changes. Is it even possible to adjust a method in a third party library from your own script? – Seth Jones Mar 06 '23 at 16:42
  • It is definitely possible to replace methods of imported modules / libraries. It is frequently done in unit testing with [mock.patch](https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch) and also slightly more rarely in general. Did you edit the library files after the import or before the import? If it was after the import, you should use [importlib.reload](https://docs.python.org/3/library/importlib.html#importlib.reload) to make the changes. – arrmansa Mar 06 '23 at 16:51