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 :
partialobjetospartialson como objetosfunctionen 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 objetospartialdefinidos 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.