2017-08-14 2 views
4

は、所定の位置に他のいくつかのクラスLesserClassを使用して、クラスNiceClass私はオーバーライド使用されるクラスは、

# NiceClass.py 

class LesserClass: 
    ... 
    # stuff 
    ... 

class NiceClass: 
    ... 
    # Lots of use of lesser class in here... 
    ... 

今私はどこにでもLesserClassするのではなく、自分自身のクラスMyLesserClassを使用したい編集することはできませんがあるとNiceClass

# MyNiceClass.py 

from NiceClass import NiceClass 
from NiceClass import LesserClass as oldLesserClass 

class LesserClass(oldLesserClass): 
    ... 
    # Some extra stuff 
    ... 

class MyNiceClass(NiceClass): 
    ... 
    # Everywhere LesserClass was used I now want to use MyLesserClass 
    ... 

しかしMyNiceClassにおけるすべての非オーバーライドされたメソッドの継承されたバージョンが古いからLesserClassを使用します。。

NiceClassの定義全体をコピーしてMyNiceClass.pyにコピーすれば、すべてがうまくいくはずです。

私は、名前空間全体ではなくソースコードを継承したいと思うようです。多分継承は間違った方法ですか?

+1

あなたの質問はまだ不明です。より明確にしてください。あなたの期待と問題は何ですか? –

答えて

2

これはNiceClassのメソッドに限定されており、クラスLesserClassを使用しています。あなたはMyNiceClass内部メソッドがMyLesserClass代わりのLesserClassを使用したい場合は

さて、あなたはそれらのメソッドの__globals__辞書を更新し、MyLesserClassに名前'LesserClass'ポイントを作ることができます。

はここ__getattribute__をオーバーライドすることで、同じことを証明する簡単な例です:

class A: 
    a = 'A.a' 
    b = 'A.b' 


class B: 
    def func_a(self): 
     print(A.a) 

    def func_b(self): 
     print(A.b) 


class C: 
    a = 'C.a' 
    b = 'C.b' 


class D(B): 
    def func_a(self): 
     print(C.a) 

    def __getattribute__(self, attr): 
     value = object.__getattribute__(self, attr) 
     if callable(value): 
      value = update_namespace(value, {'old': {'name': 'A', 'obj': A}, 'new': {'obj': C}}) 
     return value 


def update_namespace(func, namespace): 
    def wrapper(*args, **kwargs): 
     # Update the globals 
     func.__globals__[namespace['old']['name']] = namespace['new']['obj'] 
     val = func(*args, **kwargs) 
     # Restore it back to the actual value 
     func.__globals__[namespace['old']['name']] = namespace['old']['obj'] 
     return val 
    return wrapper 


d = D() 
d.func_a() # This should print C.a 
d.func_b() # This should print C.b 

出力:

C.a 
C.b 
関連する問題