2017-09-13 9 views
3

タイトルは私がやろうとしていることの最善の説明ではないかもしれませんが、私はこれを何と呼ぶべきか分かりません。私は、 "デコレータ"、 "記述子"、 "メタクラス"のような名前を持つ様々な一見関連した概念に出くわしましたが、私はこれらのアプローチ(もしあれば)をさらに調査しなければなりません!私はこのようなMyGreeterのインスタンスを使用できるようにしたいと思いクラス属性から派生した名前を持つメソッドを動的に定義していますか?

class AnimalGreeter(object): 

    def __init__(self, greeting): 
     self.greeting = greeting 

    def greet(self, animal): 
     print(self.greeting + ", " + animal + "!") 

class MyGreeter(AnimalGreeter): 

    animals = ['dog', 'parrot'] 

:効果的

greeter = MyGreeter("What's up") 
greeter.parrot 
# "What's up, parrot!" 

、私はそれが私かのように機能したいと思います

は、以下のクラスを考えます代わりにMyGreeterを次のように定義しました:

class MyGreeter(AnimalGreeter): 

    @property 
    def dog(self): 
     self.greet('dog') 

    @property 
    def parrot(self): 
     self.greet('parrot') 

言い換えれば、クラス(MyGreeter)の属性(animals)から派生した名前を持つメソッド(dog()など)を動的に定義したいと思います。

これを行うにはどのような方法が最適ですか?どうもありがとう!

+2

ただ、 '' __getattr __(自己、動物)を実装。 – AChampion

+0

ここでは手伝っていますが、私はあなたのユースケースに興味があります。なぜあなたはこの振る舞いを必要としますか? – FabienP

+1

@FabienP、私のケースでは 'AnimalGreeter'はDjangoモデルで、' MyGreeter'は設定可能なファイル名で画像を扱うカスタムミックスインです。私はDjangoのテンプレートの画像URLにアクセスしたいが、Djangoのテンプレートシステムでは引数をインスタンスメソッドに渡すことはできません。ですから、私はテンプレートの 'model.image_url( 'large')'と同等のことをすることはできません。しかし、私は 'model.large_image_url'のようなテンプレートのインスタンスプロパティにアクセスできます。 – tino

答えて

4

これはちょうど__getattr__()を実装することです簡単な方法は、例えば:

class MyGreeter(AnimalGreeter): 
    animals = {'dog', 'parrot'} 

    def __getattr__(self, animal): 
     if animal in self.animals: 
      return self.greet(animal) 
     raise AttributeError("'{}' object unknown animal '{}'".format(type(self).__name__, animal)) 

>>> greeter = MyGreeter("What's up") 
>>> greeter.parrot 
What's up, parrot! 
>>> greeter.cat 
... 
AttributeError: 'MyGreeter' object unknown animal 'cat' 
+0

ありがとう!これは私が遭遇した提案の1つでしたが、オーバーヘッドについて心配する必要があるかどうかは不明でした。 'AnimalGreeter'には頻繁にアクセスされる多くの属性があります。これは、インスタンス属性にアクセスするたびに実行されますか? – tino

+2

@tinoいいえ、 '__getattr__'は、「存在しない」属性にアクセスする場合にのみ呼び出されます。つまり、AttributeErrorがスローされるときに呼び出されます。 [ドキュメントを読む](https://docs.python.org/3/reference/datamodel.html#object.__getattr__) –

+0

@Rawing、ああ、それは完璧な意味があります。リンクと説明をありがとう! – tino

関連する問題