2013-08-16 4 views
1

Я установил пакет (схема) python, который имеет несколько классов, расширенных от базового класса.Можете ли вы изменить базовый класс пакета в python?

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

class StringType(BaseType): 
    ... 

class IntType(BaseType): 
    ... 

Я хотел был бы иметь возможность изменить класс BaseType, поэтому он примет дополнительные переменные конструктора.

Я знаю, что я мог бы определить свои собственные классы на их основе, но мне было интересно, действительно ли в Python есть способ изменить только базовый класс?

Спасибо, Бен

ответ

2

Конечно, вы можете. Просто сделайте BaseClass.__init__ = your_new_init. Это не работает, если BaseClass реализован в C (и я считаю, что не может надежно изменить специальный метод класса, реализованного на C, вы можете сделать это в C самостоятельно).

Я считаю, что вы хотите сделать, это огромный хак, что только вызовет проблемы, поэтому я настоятельно советую вам не заменить __init__ базового класса, который вы даже не писать.

Пример:

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' 
+0

Большое спасибо за решение! Вы правы, но это взломать, поэтому я попытаюсь найти другой способ. Интересно посмотреть, как это будет работать. –

0

Вы, вероятно, можете редактировать исходники, где определен базовый класс, или сделать копию пакета и редактировать исходный код для вашего конкретного проекта.

Смотрите также: How do I find the location of my Python site-packages directory?

Смежные вопросы