0

クラス「A」のインスタンスを格納し、「A」のメソッドのラップされたバージョンを継承する辞書クラス「D」を作成するにはどうすればよいですか?

たとえば、a = A() で、a.first() が「a」に対して何かを実行し、何らかのオブジェクトを返す関数であるとします。次に、 d = D({'k0': a0, 'k1': a1}) に {'k0': a0.first(), 'k1': a1.first を返す属性 d.first() を持たせたい()} を呼び出し、first() の呼び出しと同様に、a0 と a1 の基になるデータを変更します。

さらに、dictクラスにまだ存在しないメソッド(およびおそらく属性)のみを公開したい(ストンプなし)そしてこれを動的に実行したい(Aのメソッドのハードコーディングなし、すべてを入力する方法をすでに知っている)メソッドは手作業で)。'_' で始まらないメソッドのみを扱うことを検討してください。

また、戻り値の型 (後処理、ラッピングなど) に応じて、呼び出しからの出力の処理を 'D' に実行してもらいたいと思います。

これはちょっと悪い考えのように思えますが、どのようなアプローチがあるのか​​ を理解したいだけです。これまでの私の読書から、多重継承を使用して独自の__new__関数を作成したり、メタクラス化で何か他のことをしたりできるようです。しかし、教祖でない限り、一般的にいじってはいけないという伝承がある__new__ので、これは私を躊躇させます. これを行うためのデコレータのトリックはありますか? inspect モジュールを使用してクラス「A」をトラバースすることもできると思いますが、これはハックのように感じます。

更新:非常に具体的な例として。pandas.DataFrames のディクショナリがあり、iPython で動作するメソッドのタブ補完も含めて、コレクションを単一の DataFrame のように表示して動作させたいとします (そして、pandas.Panel を使用していません)。簡単にするために、読み取り専用の動作 (インデックス作成と選択) のみを考慮してください。 '] は、キー 'k0' に対応する辞書の値を返す必要があります。ハードコーディングとgetattrの組み合わせは、私が望むことを行いますが、より少ないハードコーディングでこれを行う方法を探っています。

これは、含まれるオブジェクトのように動作するイテラブルを動的に生成したい場合によくある設計上の問題だと思います。

4

2 に答える 2

1

これらはそれぞれ、限定的なテストで機能します。

#! /usr/bin/python3
class D(dict):
    def __getattr__(self, name):
        return lambda *args, **kw: {
            k:getattr(v,name)(*args, **kw) for k,v in self.items() }

class D(dict):
    def __getattr__(self, name):
        def proxy(*args, **kw):
            d2 = {k:getattr(v,name)(*args, **kw) for k,v in self.items()}
            # Post-process if required
            return d2
        return proxy

d = D()

d['k1']='a1'
d['k2']='a2'
d['k3']='33'

print(d.capitalize())  # No-arg form passed to str, not dict
print(d.replace('a', 'Hello')) # Arguments
print(d.get('k1'))  # .get() satisified by dict, not str
于 2013-09-03T04:32:55.150 に答える
0

これは少し奇妙な質問ですが、「D」が構造的に何であるかに大きく依存します。D が単なるデータ構造である場合、ディクショナリをオブジェクトでパックし、subcript して、次のように関数を呼び出すことは完全に有効です。

class A(object):
   def __init__(self,x):
       self.x = x
   def first(self):
       return self.x

a = A(7)
b = A(3)
d = {'X':a,'Y':b}
print d['X'].first()

これに加えて、すべての「最初」が必要な場合は、次のようにすることができます。

firsts = {}
for i,j in d:
    firsts[i]=j.first()

ただし、あなたの課題はもう少し複雑で、安全ではないようです。辞書のオブジェクトにkeys()メソッドがある場合はどうなりますか? keys()どちらが優先され、それが辞書の場合、コンテンツのメソッドにアクセスするにはどうすればよいですか?

私が提案したいのは、質問をより具体的に再構成または再質問することです。まず、辞書のオブジェクトは何を表していますか? さらに重要なことに、辞書は何を表しているのでしょうか?

于 2013-09-03T03:04:46.333 に答える