2013-05-18 1 views
25

、私は次のように他のより一般的なクラスメソッドを使用して、いくつかのクラスメソッドを定義しようとしている:私はそれらのいずれかの方法を起動しようとするとfunctools.partialは

class RGB(object): 
    def __init__(self, red, blue, green): 
     super(RGB, self).__init__() 
     self._red = red 
     self._blue = blue 
     self._green = green 

    def _color(self, type): 
     return getattr(self, type) 

    red = functools.partial(_color, type='_red') 
    blue = functools.partial(_color, type='_blue') 
    green = functools.partial(_color, type='_green') 

をしかし、私は得る:

rgb = RGB(100, 192, 240) 
print rgb.red() 
TypeError: _color() takes exactly 2 arguments (1 given) 

rgb.red(rgb)が動作しているので自己_colorには渡されません。

答えて

30

ファンクションでパーシャルを作成していますが、メソッドではありません。 functools.partial()オブジェクトはディスクリプタではなく、それ自体でself引数を追加することはなく、メソッド自体として動作することはできません。 ラップバインドされたメソッドまたは関数は、バインドされていないメソッドではまったく機能しません。これはdocumentedです:

partialオブジェクトは、彼らが呼び出し可能な、弱い参照可能であるという点でfunctionオブジェクトのようなもの、および属性を持つことができます。重要な違いがいくつかあります。たとえば、__name__および__doc__の属性は自動的には作成されません。また、クラス内で定義されたオブジェクトは、静的メソッドのように動作し、インスタンス属性のルックアップ中にバインドされたメソッドに変換されません。partial

代わりにpropertyを使用してください。あなたはここに新しいfunctools.partialmethod() objectを使用することができ、Pythonの3.4のよう

class RGB(object): 
    def __init__(self, red, blue, green): 
     super(RGB, self).__init__() 
     self._red = red 
     self._blue = blue 
     self._green = green 

    def _color(self, type): 
     return getattr(self, type) 

    @property 
    def red(self): return self._color('_red') 
    @property 
    def blue(self): return self._color('_blue') 
    @property 
    def green(self): return self._color('_green') 

;:これら記述子であります

class RGB(object): 
    def __init__(self, red, blue, green): 
     super(RGB, self).__init__() 
     self._red = red 
     self._blue = blue 
     self._green = green 

    def _color(self, type): 
     return getattr(self, type) 

    red = functools.partialmethod(_color, type='_red') 
    blue = functools.partialmethod(_color, type='_blue') 
    green = functools.partialmethod(_color, type='_green') 

をしかしpropertyオブジェクトは、単純な属性として使用することができながら、呼ばれなければならthese'd:それはインスタンスにバインドされたときに正しいことをやります。

+0

入手しました。ありがとう。 – Arjor

+1

'__init__'の' self.red = functools.partial(RGB._color、self、 'red') 'についてどうですか? Python2との互換性もあります。 – dashesy

+2

@dashesy:確かですが、それは各インスタンスにそれらのオブジェクトを置きます(メモリコスト)。また、サブクラスがそれらを置き換えるのが難しくなります。 –