如何在Python中扩展第三方库?

时间:2019-05-08 06:24:40

标签: python coding-style

我有一个第三方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本身。

问题是: 我将如何去做?

我的想法:

  • 通过调用super并使用副本来覆盖A.get_B 构造函数:
    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 方法上:解释器决定在实例化new_b之后立即删除old_b对象,这将删除old_b.b对象,然后删除new_b.b。变为无,并且 数据库连接已关闭。

复制old_b.b将无济于事,因为数据库连接仍将关闭。 而且,有时创建副本构造函数(如果对象进行了一些转换)甚至是不合理的。

  • 我当然可以将A.get_B的代码复制粘贴到Extended_A并用Extended_B替换B,但这对我来说似乎并不是一种优雅的方法。 在这种情况下,您能否建议以Python方式做得最好?

2 个答案:

答案 0 :(得分:0)

据我所知,您可以通过保留对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

答案 1 :(得分:0)

您是否正在寻找类似的东西?:

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