Python functools.partial关于类方法

Python functools.partial关于类方法,python,exception,methods,functools,Python,Exception,Methods,Functools,我尝试使用另一个更通用的类方法定义一些类方法,如下所示: 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 ge

我尝试使用另一个更通用的类方法定义一些类方法,如下所示:

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没有传递给
\u color
,因为
rgb.red(rgb)
可以工作。

您是在函数上创建分部,而不是在方法上创建分部
functools.partial()
对象不是描述符,它们本身不会添加
self
参数,并且不能充当方法本身。您只能包装绑定的方法或函数,它们根本不适用于未绑定的方法。这是:

partial
对象类似于
function
对象,因为它们是可调用的、弱可引用的,并且可以具有属性。有一些重要的区别。例如,
\uuuuuu name\uuuuu
\uuuuu doc\uuuuu
属性不会自动创建。此外,类中定义的
partial
对象的行为类似于静态方法,在实例属性查找期间不会转换为绑定方法

使用
属性
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')
从Python3.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)

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

但是必须调用这些属性,而
属性
对象可以用作简单属性。

partialmethod的问题是它与
inspect.signature
functtools.wrapps

奇怪的是,如果您自己使用重新实现
functools.partial

#实施来源:
# https://docs.python.org/3/library/functools.html#functools.partial
def partial(func,/,*参数,**关键字):
def newfunc(*fargs,**fkeywords):
newkeywords={**keywords,**fkeywords}
return func(*args,*fargs,**newkeywords)
newfunc.func=func
newfunc.args=args
newfunc.keywords=关键字
返回newfunc

原因是
newfunc
是一个真正的函数,它实现了与
newfunc.\uuuu get\uuuu
的交互。而
type(functools.partial)
是一个覆盖了
\uuuu调用的自定义类。类不会自动添加
self
参数。

那么
self.red=functools.partial(RGB.\u color,self,'red')
中的
呢?dashesy:当然,但这会将这些对象放在每个实例上(内存开销),也会使子类更难替换它们。这是一个有用的问题,我不想偏离主要观点,但作为代码的一个附带问题,我想知道为什么要编写super(RGB,self)。\uu init\uuuuuuu(),当RGB从object?@CaptainLepton继承时,这是一个很好的做法,以防有一天有人添加一个超类。@michaelb958--GoFundMonica你的意思是将
RGB
超类添加到一个新编写的子类中?
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