0

授業がある:

class A(object):
    def do_computing(self):
        print "do_computing"

で、〜がある:

new_class = type('B', (object,), {'a': '#A', 'b': '#B'})

私が達成したいのは、クラス A のすべてのメソッドとプロパティをクラス B のメンバーにすることです。クラス A は、そのような要素を 0 から N まで持つことができます。全員をB級にしたい。

これまでのところ、次のようになります。

methods = {}

for el in dir(A):
    if el.startswith('_'):
        continue

    tmp = getattr(A, el)

    if isinstance(tmp, property):
        methods[el] = tmp

    if isinstance(tmp, types.MethodType):
        methods[el] = tmp

instance_class = type('B', (object,), {'a': '#A', 'b': '#B'})

for name, func in methods.items():
    new_method = types.MethodType(func, None, instance_class)
    setattr(instance_class, name, new_method)

しかし、私が実行すると:

instance().do_computing()

エラーが発生します:

TypeError: unbound method do_computing() must be called with A instance as first argument (got B instance instead)

なぜ私はそれをしなければならなかったのですか?多くのレガシー コードがあり、古いオブジェクトのふりをする派手なオブジェクトが必要ですが、実際にはそうではありません。

もう1つ重要なこと。バックグラウンドで多くの魔法が発生するため、継承を使用できません。

4

4 に答える 4

1

ファサードを作成していますか?多分あなたはこのようなものが欲しいです:

Python 2.5 でファサードを作成する

http://en.wikipedia.org/wiki/Facade_pattern

委任者を使用することもできます。wxpython AGW の例を次に示します。

_methods = ["GetIndent", "SetIndent", "GetSpacing", "SetSpacing", "GetImageList", "GetStateImageList",
        "GetButtonsImageList", "AssignImageList", "AssignStateImageList", "AssignButtonsImageList",
        "SetImageList", "SetButtonsImageList", "SetStateImageList", 'other_methods']

def create_delegator_for(method):
"""
Creates a method that forwards calls to `self._main_win` (an instance of :class:`TreeListMainWindow`).

:param `method`: one method inside the :class:`TreeListMainWindow` local scope.
"""

    def delegate(self, *args, **kwargs):
        return getattr(self._main_win, method)(*args, **kwargs)
    return delegate

# Create methods that delegate to self._main_win. This approach allows for
# overriding these methods in possible subclasses of HyperTreeList
for method in _methods:
    setattr(HyperTreeList, method, create_delegator_for(method))    

これらのラップクラスメソッドに注意してください...つまり、両方の関数が署名 likedef func(self, some, other, args)を取り、 like と呼ばれるように意図されていますself.func(some, args)。クラス関数を非クラス関数にデリゲートする場合は、デリゲーターを変更する必要があります。

于 2013-10-15T15:25:41.717 に答える
1

私が何かを見逃していない限り、継承でこれを行うことができます:

class B(A):
    def __init__(self):
        super(B, self).__init__()

それで:

>>> b = B()
>>> b.do_computing()

do_computing

編集:cms_mgrはコメントで同じことを言い、インデントも修正しました

于 2013-10-15T15:09:28.890 に答える
0

親クラスから次のように継承できます。

class Awesome():

    def method_a():
        return "blee" 


class Beauty(Awesome):

    def __init__(self):
        self.x = self.method_a()

b = Beauty()
print(b.x)
>>> "blee"

これは自由に入力されたものですが、それでもロジックは同じであり、機能するはずです。

次のように setattr を使用して楽しいことを行うこともできます。

#as you can see this class is worthless and is nothing 
class blee():
    pass 

b = blee()
setattr(b, "variable_1", "123456")
print(b.variable_1)
>>> 123456

基本的に、setattr を使用して任意のオブジェクト、メソッドをクラス インスタンスに割り当てることができます。

編集: setattr を使用していたことに気付きました;)

お役に立てれば!

于 2013-10-15T15:10:51.000 に答える