library python exception methods functools

python - library - functools.partial en el método de la clase



python 3 reduce (1)

Estoy tratando de definir algunos métodos de clase usando otro método de clase más genérico de la siguiente manera:

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'')

Pero cuando intento invocar cualquiera de esos métodos, obtengo:

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

Supongo que no se pasa a _color porque rgb.red(rgb) funciona.


Está creando parciales en la función , no en el método. functools.partial() objetos functools.partial() no son descriptores, ellos mismos no agregarán el self argumento y no pueden actuar como métodos. Solo puede envolver métodos o funciones enlazados, no funcionan en absoluto con métodos independientes. Esto está documented :

partial objetos partial son como objetos function en el sentido de que son invocables, de referencia débil y pueden tener atributos. Hay algunas diferencias importantes Por ejemplo, los atributos __name__ y __doc__ no se crean automáticamente. Además, los objetos partial definidos en las clases se comportan como métodos estáticos y no se transforman en métodos vinculados durante la búsqueda de atributos de la instancia.

Use la property s en su lugar; estos son descriptores:

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'')

A partir de Python 3.4, puede usar el nuevo objeto functools.partialmethod() aquí; hará lo correcto cuando esté vinculado a una instancia:

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'')

pero tendrían que llamarse, mientras que los objetos de property se pueden usar como atributos simples.