[英]functools.partial on class method
我正在尝试使用另一个更通用的类方法来定义一些类方法,如下所示:
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)
我猜 self 没有传递给_color
因为rgb.red(rgb)
工作。
您正在函数上创建部分,而不是方法。 functools.partial()
对象不是描述符,它们本身不会添加self
参数,也不能充当方法本身。 您只能包装绑定的方法或函数,它们根本不适用于未绑定的方法。 这是记录在案:
partial
对象类似于function
对象,因为它们是可调用的、弱可引用的,并且可以具有属性。 有一些重要的区别。 例如,__name__
和__doc__
属性不是自动创建的。 此外,类中定义的partial
对象的行为类似于静态方法,并且不会在实例属性查找期间转换为绑定方法。
改用property
s; 这些是描述符:
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')
从 Python 3.4 开始,您可以在此处使用新的functools.partialmethod()
对象; 当绑定到一个实例时,它会做正确的事情:
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
对象可以用作简单的属性。
partialmethod
的问题在于它与inspect.signature
, functools.wraps
,...不兼容。
奇怪的是,如果您使用部分文档实现示例自己重新实现functools.partial
,它将起作用:
# Implementation from:
# https://docs.python.org/3/library/functools.html#functools.partial
def partial(func, /, *args, **keywords):
def newfunc(*fargs, **fkeywords):
newkeywords = {**keywords, **fkeywords}
return func(*args, *fargs, **newkeywords)
newfunc.func = func
newfunc.args = args
newfunc.keywords = keywords
return newfunc
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 = partial(_color, type='_red')
blue = partial(_color, type='_blue')
green = partial(_color, type='_green')
rgb = RGB(100, 192, 240)
print(rgb.red()) # Print red
原因是newfunc
是一个真正的函数,它使用newfunc.__get__
实现了描述符协议。 而type(functools.partial)
是一个覆盖了__call__
的自定义类。 类不会自动添加self
参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.