[英]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.