简体   繁体   English

您可以在python中修改包的基类吗?

[英]Can you modify a package's base class in python?

I've installed a python package (schematic), which has a number of classes extended from a base class. 我安装了一个python软件包(示意图),该软件包具有从基类扩展的许多类。

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

class StringType(BaseType):
    ...

class IntType(BaseType):
    ...

I would like to be able to modify the BaseType class, so it would accept additional constructor variables. 我希望能够修改BaseType类,因此它将接受其他构造函数变量。

I know I could define my own classes based on these, but I was wondering if there's actually a way in Python to modify just the base class? 我知道我可以基于这些定义自己的类,但是我想知道Python中是否真的有一种方法可以只修改基类?

Thank you, Ben 谢谢你,本

Of course you can. 当然可以。 Simply do BaseClass.__init__ = your_new_init . 只需执行BaseClass.__init__ = your_new_init This does not work if the BaseClass is implemented in C however(and I believe you cannot reliably change a special method of a class implemented in C; you could do this writing in C yourself). 但是,如果BaseClass是用C实现的,那么这是行不通的(我相信您不能可靠地更改用C实现的类的特殊方法;您可以自己用C编写此代码)。

I believe what you want to do is a huge hack, that will only cause problems, so I strongly advise you to not replace __init__ of a base class that you didn't even write. 我相信您想要做的是一个巨大的hack,只会造成问题,因此,我强烈建议您不要替换甚至没有编写的基类的__init__

An example: 一个例子:

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'

You can probably edit the sourcefiles where the base class is defined, or make a copy of the package and edit the source for your specific project. 您可能可以编辑定义了基类的源文件,或者制作该程序包的副本并编辑特定项目的源代码。

See also: How do I find the location of my Python site-packages directory? 另请参阅: 如何找到Python site-packages目录的位置?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM