你能用python修改包的基类吗?

2024-06-16 16:04:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我安装了一个python包(schematic),它有许多从基类扩展而来的类。你知道吗

class BaseType(object):
    def __init__(self, required=False, default=None ...)
    ...

class StringType(BaseType):
    ...

class IntType(BaseType):
    ...

我希望能够修改BaseType类,这样它就可以接受额外的构造函数变量。你知道吗

我知道我可以基于这些定义自己的类,但我想知道Python中是否真的有方法只修改基类?你知道吗

谢谢你,本


Tags: selfnonefalsedefault定义objectinitdef
2条回答

你当然可以。只要做BaseClass.__init__ = your_new_init。但是,如果BaseClass是在C中实现的,这就行不通了(我相信您不能可靠地更改用C实现的类的特殊方法;您可以自己用C编写)。你知道吗

我相信你想做的是一个巨大的黑客,那只会引起问题,所以我强烈建议你不要替换你甚至没有写的基类。你知道吗

举个例子:

In [16]: class BaseClass(object):
    ...:     def __init__(self, a, b):
    ...:         self.a = a
    ...:         self.b = b
    ...:         

In [17]: class A(BaseClass): pass

In [18]: class B(BaseClass): pass

In [19]: BaseClass.old_init = BaseClass.__init__ #save old init if you plan to use it 

In [21]: def new_init(self, a, b, c):
    ...:     # calling __init__ would cause infinite recursion!
    ...:     BaseClass.old_init(self, a, b)
    ...:     self.c = c

In [22]: BaseClass.__init__ = new_init

In [23]: A(1, 2)   # triggers the new BaseClass.__init__ method
                                     -
TypeError                                 Traceback (most recent call last)
<ipython-input-23-09f95d33d46f> in <module>()
  > 1 A(1, 2)

TypeError: new_init() missing 1 required positional argument: 'c'

In [24]: A(1, 2, 3)
Out[24]: <__main__.A at 0x7fd5f29f0810>

In [25]: import numpy as np

In [26]: np.ndarray.__init__ = lambda self: 1   # doesn't work as expected
                                     -
TypeError                                 Traceback (most recent call last)
<ipython-input-26-d743f6b514fa> in <module>()
  > 1 np.ndarray.__init__ = lambda self: 1

TypeError: can't set attributes of built-in/extension type 'numpy.ndarray'

您可能可以编辑定义基类的源文件,或者制作包的副本并编辑特定项目的源文件。你知道吗

另见:How do I find the location of my Python site-packages directory?

相关问题 更多 >