这些 `.` 属性绑定在 `functools.partial` 的实现中是必需的吗?
Are these `.` attribute bindings necessary in the implementation of `functools.partial`?
docs.python.org 表示 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
(注意:/
用于表示 func
作为 partial
的仅位置参数。参见 [1]。)
如果我没理解错的话,当在嵌套函数中引用变量时,例如newfunc
,Python首先在嵌套函数中查找变量定义。如果在那里找不到定义,Python 接下来将在封闭范围内查找定义(即外部函数;在本例中为 partial
)。那么,上面 newfunc
的显式 .func
、.args
和 .keywords
属性绑定真的有必要吗?我尝试了一个没有上述绑定的示例,它 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
# p0, p1, p2 are positional arguments
# kw0, kw1, kw2 are keyword-only arguments
def foo3(p0, p1, p2, *, kw0, kw1, kw2):
return 100*p2 + 10*p1 + 1*p0, kw0 + kw1 + kw3
foo2 = partial(foo3, 1, kw0=1+1j)
print(foo2(2,3,kw1=2+2j, kw2=3+3j)) # (321, (6+6j))
如果 keywords
或 fkeywords
词典包含带有 func
、args
或 keywords
的项目,是否需要 .
绑定作为关键字?这些是必要的例子是什么?据我所知,这不是原因,因为以下工作:
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
# p0, p1, p2 are positional arguments
# kw0, kw1, kw2 are keyword-only arguments
def foo3(p0, p1, p2, kw0, kw1, kw2, **kwargs):
return 100*p2 + 10*p1 + 1*p0, kw0 + kw1 + kw2 + sum(kwargs.values())
foo2 = partial(foo3, 1, kw0=1+1J, func=10, args=10j, keywords=100+100j)
print(foo2(2,3,kw1=2+2J, kw2=3+3J, func=20, args=20j, keywords=200+200j)) # (321, (226+6j))
[1] https://docs.python.org/3/whatsnew/3.8.html#positional-only-parameters
我想你可以看看 partial
class 实现,以帮助你更好地理解。
以下(Python 3.9.5
)
class partial:
"""New function with partial application of the given arguments
and keywords.
"""
__slots__ = "func", "args", "keywords", "__dict__", "__weakref__"
def __new__(cls, func, /, *args, **keywords):
if not callable(func):
raise TypeError("the first argument must be callable")
if hasattr(func, "func"):
args = func.args + args
keywords = {**func.keywords, **keywords}
func = func.func
self = super(partial, cls).__new__(cls)
self.func = func
self.args = args
self.keywords = keywords
return self
def __call__(self, /, *args, **keywords):
keywords = {**self.keywords, **keywords}
return self.func(*self.args, *args, **keywords)
...
当您将 self
替换为 newfunc
时,它们几乎是一样的。
docs.python.org 表示 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
(注意:/
用于表示 func
作为 partial
的仅位置参数。参见 [1]。)
如果我没理解错的话,当在嵌套函数中引用变量时,例如newfunc
,Python首先在嵌套函数中查找变量定义。如果在那里找不到定义,Python 接下来将在封闭范围内查找定义(即外部函数;在本例中为 partial
)。那么,上面 newfunc
的显式 .func
、.args
和 .keywords
属性绑定真的有必要吗?我尝试了一个没有上述绑定的示例,它 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
# p0, p1, p2 are positional arguments
# kw0, kw1, kw2 are keyword-only arguments
def foo3(p0, p1, p2, *, kw0, kw1, kw2):
return 100*p2 + 10*p1 + 1*p0, kw0 + kw1 + kw3
foo2 = partial(foo3, 1, kw0=1+1j)
print(foo2(2,3,kw1=2+2j, kw2=3+3j)) # (321, (6+6j))
如果 keywords
或 fkeywords
词典包含带有 func
、args
或 keywords
的项目,是否需要 .
绑定作为关键字?这些是必要的例子是什么?据我所知,这不是原因,因为以下工作:
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
# p0, p1, p2 are positional arguments
# kw0, kw1, kw2 are keyword-only arguments
def foo3(p0, p1, p2, kw0, kw1, kw2, **kwargs):
return 100*p2 + 10*p1 + 1*p0, kw0 + kw1 + kw2 + sum(kwargs.values())
foo2 = partial(foo3, 1, kw0=1+1J, func=10, args=10j, keywords=100+100j)
print(foo2(2,3,kw1=2+2J, kw2=3+3J, func=20, args=20j, keywords=200+200j)) # (321, (226+6j))
[1] https://docs.python.org/3/whatsnew/3.8.html#positional-only-parameters
我想你可以看看 partial
class 实现,以帮助你更好地理解。
以下(Python 3.9.5
)
class partial:
"""New function with partial application of the given arguments
and keywords.
"""
__slots__ = "func", "args", "keywords", "__dict__", "__weakref__"
def __new__(cls, func, /, *args, **keywords):
if not callable(func):
raise TypeError("the first argument must be callable")
if hasattr(func, "func"):
args = func.args + args
keywords = {**func.keywords, **keywords}
func = func.func
self = super(partial, cls).__new__(cls)
self.func = func
self.args = args
self.keywords = keywords
return self
def __call__(self, /, *args, **keywords):
keywords = {**self.keywords, **keywords}
return self.func(*self.args, *args, **keywords)
...
当您将 self
替换为 newfunc
时,它们几乎是一样的。