Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中扩展第三方库?_Python_Coding Style - Fatal编程技术网

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

如何在Python中扩展第三方库?,python,coding-style,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_

我有一个第三方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的功能

为此,我(大概)需要创建一个扩展的类

我还想知道A.get_B是否返回了扩展_B的实例,而不是B本身

问题是: 我该怎么做呢

我的想法是:

  • 通过调用super并使用副本重写A.get_B 建造商:
本例中的问题在于del方法:解释器决定在实例化新的\u b对象后立即删除旧的\u b对象,这会删除旧的\u b.b对象,然后新的\u b.b变为无,而 数据库连接已关闭

复制旧的_b.b没有任何好处,因为数据库连接仍将关闭。 此外,有时创建一个副本构造函数(如果对象经历了一些转换)甚至是不必要的

  • 当然,我可以将A的代码复制粘贴到扩展A,并用扩展B替换B,但这对我来说似乎不是一个优雅的方法。 你能建议在这种情况下,从蟒蛇的角度看,什么是最好的吗

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

你在找这样的东西吗

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
[107]中的
:类扩展_A(A):
…:def get_B(自身):
…:old_b=super()
…:new_b=扩展自旧(self,old_b)
…:返回新的
...:
...:
…:类扩展_B(B):
…:def from_old_B(self,old_B):
…:打印(“{}.format的实例(old_B))
…:mod_值=旧_B.B**2
…:打印(“修改值:{}”。格式(mod_值))
…:返回mod_值
...:
...:
In[108]:a=扩展的_a(1,2)
在[109]中:a.get_B()
实例
修改值:9
Out[109]:9

Extended_A(A)
返回
old_b
,这应该会给你一个
b
的实例:
而不是
这里的要点是我想让b返回我修改过的扩展_b实例。我刚刚读到了关于Python中重新分类的内容,所以我想我可能会先返回旧的,然后再执行旧的。虽然它可能有一些警告,但不确定是的,我想我可以这样做,假设b没有定义插槽。不知道在这种情况下该怎么办。@AntonBohdanov为什么会有不同?对不起,我的意思是“a没有插槽”。是的,插槽不是继承的,所以我们的想法是不在A上定义插槽。但是不继承插槽是一种不好的做法AFAIK@AntonBohdanov定义
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu插槽
纯粹涉及性能(访问时间和内存)。
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