Извлечение и изоляция функции Python с учетом экземпляра класса - PullRequest
1 голос
/ 29 мая 2020

Предположим, мне дан экземпляр класса Python. В этом классе есть функция, которую я хотел бы выделить и изолировать от класса. Последняя функция должна иметь доступ к значениям атрибутов исходного класса, но в противном случае она не должна вызывать этот класс вообще.

Моя мотивация состоит в том, что я хочу скомпилировать функцию, используя jit из numba , но я не хочу компилировать весь класс, используя jitclass

As В качестве конкретного примера рассмотрим следующий класс. В идеале я не хочу изменять этот код:

class Adder:
    """
    A minimal callable class with keyword arg
    """
    def __init__(self, num=4):
        self.num = num
    def add(self, val1, val2):
        return val1 + val2
    def add_default(self, val1, val2):
        return self.num + val1 + val2

Теперь я создаю экземпляры этих объектов, а затем пытаюсь скомпилировать их методы с помощью numba. Это работает, когда метод экземпляра не использует ни один из атрибутов объекта

from numba import jit

a = Adder(num=1)
print(a.add(7, 8)) # 15
add_fast = jit(a.add)
print(add_fast(7, 8)) # 15

Однако это прерывается, когда я пытаюсь использовать метод, требующий атрибут класса

from numba import jit

a = Adder(num=1)
print(a.add_default(7, 8)) # 16
add_default_fast = jit(a.add_default)
print(add_default_fast(7, 8)) # NotDefinedError: Variable 'self' is not defined.

Я пробовал используя лямбда-функцию, но она все еще внутренне ссылается на класс и нарушает jit. В идеале я хочу извлечь метод экземпляра, а также значения всех атрибутов экземпляра и создать новую функцию, которая заменяет все self. переменные их значениями из атрибутов экземпляра.

Есть ли простой способ сделать это? Я надеюсь на решение, которое не требует рефакторинга класса.

1 Ответ

1 голос
/ 29 мая 2020

Попробуйте следующее:

def add_default(a,*args):
    return Adder.__dict__['add_default'](a,*args)

add_default_fast = jit(add_default,forceobj=True)
print(add_default_fast(a,7, 8)) # 16

Вместо 'a' вы можете передать функции любой python объект, имеющий атрибут 'num'

(см. Также: Python: взломать, чтобы вызвать метод объекта, не относящегося к его классу для этого трюка dict , который позволяет явно указать аргумент self метода)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...