Try implementing extension method in python

What is an extension method?

-From Extension Method (C # Programming Guide)

Extension methods allow you to "add" a method to an existing type without creating a new derived type, recompiling, or modifying the original type.

Try to implement

Since it is difficult to realize an extension method like C #, here we aim to wrap an instance of the target type in an extension class so that object-oriented method execution is possible, or it can be executed as a simple function ( Programming by transfer, not inheritance).

According to the Official Document, by implementing __get__, it is possible to control whether it behaves as a function or a method, so I will put some work here.

The following code replaces the self passed to the method with self .__ root __ to implement a pseudo-extension method.

from functools import wraps
from types import MethodType

class ExtensionMethod:
    def __init__(self, func):
        self.__func__ = func

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self.__func__  #If there is no instance, the function is returned as it is
        func = self.__func__

        @wraps(func)  #Inherit function argument information, etc.
        def wrapper(self, *args, **kwargs):
            return func(getattr(self, "__root__"), *args, **kwargs)  #self to self.__root__Replace with

        return MethodType(wrapper, obj)  #Returns a method that binds an instance and a function

class MyExtension:
  def __init__(self, __root__):
    self.__root__ = __root__

  @ExtensionMethod
  def add_one(self):
    return self + 1

print(MyExtension.add_one(0))  # => 1
obj = MyExtension(10)
print(obj.add_one()) # => 11

Is it like this? I'm not so happy (Oy

In many cases, simply inheriting is quicker, but since it is programmed for the __root__ interface, it has the advantage of being able to handle various types as objects without inheriting.

There may be a way to go by combining it with type checkers like mypy and pydantic.

Note

If you give a decorator to the ExtensionMethod, the decorator works for the ExtensionMethod instance.

class MyExtension:
  def __init__(self, __root__):
    self.__root__ = __root__

  @your_decorator  #Like this
  @ExtensionMethod
  def add_one(self):
    return self + 1

When accessing a method from a class, __get__ works and returns a function or method, but it should not be accessed directly during class generation.

To treat it as a function, you need to implement __call__ or take another step. (I won't introduce it here because it makes the code redundant.)

Also, if you use a static type checker such as mypy, you will get an error because the type of self does not match your own type.

@dataclass
class MyExtension:
  __root__: str

  @ExtensionMethod
  def add_one(self: str):  #Since mypy assumes MyExtension for self, an error will occur.
    return self + 1

idea

When accessing the attributes of MyExtension, if you map the attributes other than ExtensionMethod to the attributes of __root__, you may be able to implement the behavior closer to the extension method.

Summary

Not very practical.

Recommended Posts

Try implementing extension method in python
Try implementing Yubaba in Python 3
Try implementing the Monte Carlo method in Python
Simplex method (simplex method) in Python
Try gRPC in Python
Private method in python
Try 9 slices in Python
Try implementing two stacks in one array in Python
Try LINE Notify in Python
Implement extension field in Python
Implement method chain in Python
Suppressing method overrides in Python
Try implementing associative memory with Hopfield network in Python
Try python
Try using LevelDB in Python (plyvel)
Let's try Fizz Buzz in Python
Try to calculate Trace in Python
Try PLC register access in Python
Implemented label propagation method in Python
Simulate Monte Carlo method in Python
Hash method (open address method) in Python
Implementing a simple algorithm in Python 2
Try using Leap Motion in Python
Method to build Python environment in Xcode 6
Try using the Kraken API in Python
Try working with binary data in Python
Try sending a SYN packet in Python
Try drawing a simple animation in Python
Electron Microscopy Simulation in Python: Multislice Method (1)
Electron Microscopy Simulation in Python: Multislice Method (2)
Quickly try Microsoft's Face API in Python
Try text mining your diary in Python
Try hitting the YouTube API in Python
Try a functional programming pipe in Python
Try something like Python for-else in Ruby
Alignment algorithm by insertion method in Python
Quadtree in Python --2
Python in optimization
CURL in python
Geocoding in python
SendKeys in Python
Meta-analysis in Python
Unittest in python
Epoch in Python
Discord in Python
Sudoku in Python
DCI in Python
Python> try: / except:
quicksort in python
nCr in python
N-Gram in Python
Programming in python
Plink in Python
Constant in python
Lifegame in Python.
FizzBuzz in Python
Sqlite in python
StepAIC in Python
N-gram in python
LINE-Bot [0] in Python
Csv in python