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
objetospartial
son como objetosfunction
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 objetospartial
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.