Как расширить стороннюю библиотеку в Python? - PullRequest
0 голосов
/ 08 мая 2019

У меня есть сторонняя библиотека Python, которая содержит два класса:

class A:
    def __init__(self, a1, a2):
        self.a1=a1
        self.a2=a2

    def get_B(self):
        #many lines of code omitted, modifying self.a1 and self.a2
        return B(self.a1+self.a2)

class B:
    def __init__(self, b):
        self.b=b
    def __del__(self):
        del self.b # wipes out b at a system-level using c code. Assume it also closes a connection to some database

Я хотел бы расширить функциональность класса B, добавив несколько новых методов в B и изменив некоторые из методов B,

Для этого мне (предположительно) потребуется создать класс Extended_B (B).

Мне также хотелось бы, чтобы A.get_B возвратил экземпляр Extended_B, а не сам B.

Вопрос в том, как мне поступить?

Мои идеи:

  • Переопределение A.get_B путем вызова super и использования конструктора копирования:
    class Extended_A(A):
        def get_B(self):
            old_b = super().get_B()
            new_b = Extended_B.from_old_B(old_b)
            return new_b

    class Extended_B(B):
        @classmethod
        def from_old_B(cls, old_B):
            return cls(old_B.b)

Проблема в этом случае заключается в методе del : интерпретатор решает удалить объект old_b, как только будет создан экземпляр new_b, который удаляет объект old_b.b,и затем new_b.b становится None и соединение с БД закрывается.

Копирование old_b.b не принесет пользы, так как соединение с БД все еще будет закрыто.Более того, иногда даже нетривиально создать конструктор копирования (если объект претерпел некоторые преобразования).

  • Я могу, конечно, просто скопировать и вставить код A.get_B в Extended_A и заменить Bс Extended_B, но это не кажется мне элегантным подходом.Не могли бы вы посоветовать, что лучше всего сделать в питоническом смысле в этой ситуации?

Ответы [ 2 ]

0 голосов
/ 08 мая 2019

Вы ищете что-то подобное?:

In [107]: class Extended_A(A):
     ...:     def get_B(self):
     ...:         old_b = super().get_B()
     ...:         new_b = Extended_B.from_old_B(self, old_b)
     ...:         return new_b
     ...:
     ...:
     ...: class Extended_B(B):
     ...:     def from_old_B(self, old_B):
     ...:         print("Instance of {}".format(old_B))
     ...:         mod_value = old_B.b**2
     ...:         print("Modified value: {}".format(mod_value))
     ...:         return mod_value
     ...:
     ...:

In [108]: a = Extended_A(1,2)

In [109]: a.get_B()
Instance of <__main__.B object at 0x0000021591AC7080>
Modified value: 9
Out[109]: 9
0 голосов
/ 08 мая 2019

Насколько я могу судить, вы можете решить эту проблему, сохранив ссылку на old_b, чтобы он не собирал мусор:

class Extended_A(A):
    def get_B(self):
        old_b = super().get_B()
        self._cached_b = old_b
        new_b = Extended_B.from_old_B(old_b)
        return new_b
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...