从 class 构造函数创建绑定方法
Create bound method from class constructor
我有一本像 class 这样的字典,其中的方法可以 return 查看其键、值和项目。这样做的方法非常简单:
class MyType(collections.MutableMapping):
def keys(self):
return collections.KeysView(self)
但是,为如此简单的事情创建一个方法似乎毫无意义;我所做的只是将 self
传递给另一个可调用对象。我宁愿简单地将 KeysView
的 class 构造函数视为绑定方法。执行以下操作会创建一个嵌套的 class(这很好,因为有时这正是您想要的),但它看起来更接近我想要做的:
class MyType(collections.MutableMapping):
keys = collections.KeysView
Python 或其标准库是否有内置功能来执行此操作?也许是这样的:
class MyType(collections.MutableMapping):
keys = bind_constructor_as_method(collections.KeysView)
我觉得 functools
中应该有一些东西可以完成这项工作,但没有任何东西乍一看是正确答案。也许 functools.partial
,但名称并不能很好地描述我正在尝试做的事情。
我是否只需要手动滚动一个自定义描述符 class 就可以完成这样的工作?
注意:
为了工作,我经常需要使用 Python 2.7,因此尽管 Python 3.x 答案仍然受到赞赏(并且有用),但它们可能不会完全缓解问题我个人。但是,他们可能会帮助其他人解决这个问题,所以请仍然包括他们!
functools.partialmethod()
就是您要找的。这将创建一个方法,其中 self
是第一个参数。
import functools
class MyType(collections.MutableMapping):
keys = functools.partialmethod(collections.KeysView)
你还可以指定其他参数,比如如果你想将 self, 1, 2, key=5
传递给 func()
,你可以做 functools.partialmethod(func, 1, 2, key=5)
.
但请注意,这仅适用于 Python 3.4 及更高版本。
经过一番思考(以及来自 SO post here 的一些帮助),我想出了另一个适用于 Python 版本 2 和 3 的解决方案,尽管它是不那么地道。正如@Artyer 建议的那样使用 partialmethod
时发生的事情绝对不是很清楚。真的,这就是 Python 在创建新实例时在幕后所做的事情,但更加明确;你看到香肠是如何制作的。 :/
import types
import collections
class MyType(collections.MutableMapping):
def __init__(self, *args, **kwargs):
# do class specific stuff here
# create bound method per instance
self.keys = types.MethodType(collections.KeysView, self)
更好的是,我们可以在 __new__
中做到这一点,以更加确定继承 类 得到它:
import types
import collections
class MyType(collections.MutableMapping):
def __new__(cls, *args, **kwargs):
self = super(MyType, cls).__new__(cls)
# create bound method per instance
self.keys = types.MethodType(collections.KeysView, self)
return self
如果您不喜欢 types.MethodType
的相对无证性质,您可以使用 functools.partial
代替:
import functools
import collections
class MyType(collections.MutableMapping):
def __new__(cls, *args, **kwargs):
self = super(MyType).__new__(cls)
# create bound method per instance
self.keys = functools.partial(collections.KeysView, self)
return self
注意: 对于 Python 2/3 兼容性,您应该 而不是 对 types.MethodType
使用第三个可选的 class
参数;它存在于 Python 2 中,但显然在 Python 3 中被删除。
我有一本像 class 这样的字典,其中的方法可以 return 查看其键、值和项目。这样做的方法非常简单:
class MyType(collections.MutableMapping):
def keys(self):
return collections.KeysView(self)
但是,为如此简单的事情创建一个方法似乎毫无意义;我所做的只是将 self
传递给另一个可调用对象。我宁愿简单地将 KeysView
的 class 构造函数视为绑定方法。执行以下操作会创建一个嵌套的 class(这很好,因为有时这正是您想要的),但它看起来更接近我想要做的:
class MyType(collections.MutableMapping):
keys = collections.KeysView
Python 或其标准库是否有内置功能来执行此操作?也许是这样的:
class MyType(collections.MutableMapping):
keys = bind_constructor_as_method(collections.KeysView)
我觉得 functools
中应该有一些东西可以完成这项工作,但没有任何东西乍一看是正确答案。也许 functools.partial
,但名称并不能很好地描述我正在尝试做的事情。
我是否只需要手动滚动一个自定义描述符 class 就可以完成这样的工作?
注意:
为了工作,我经常需要使用 Python 2.7,因此尽管 Python 3.x 答案仍然受到赞赏(并且有用),但它们可能不会完全缓解问题我个人。但是,他们可能会帮助其他人解决这个问题,所以请仍然包括他们!
functools.partialmethod()
就是您要找的。这将创建一个方法,其中 self
是第一个参数。
import functools
class MyType(collections.MutableMapping):
keys = functools.partialmethod(collections.KeysView)
你还可以指定其他参数,比如如果你想将 self, 1, 2, key=5
传递给 func()
,你可以做 functools.partialmethod(func, 1, 2, key=5)
.
但请注意,这仅适用于 Python 3.4 及更高版本。
经过一番思考(以及来自 SO post here 的一些帮助),我想出了另一个适用于 Python 版本 2 和 3 的解决方案,尽管它是不那么地道。正如@Artyer 建议的那样使用 partialmethod
时发生的事情绝对不是很清楚。真的,这就是 Python 在创建新实例时在幕后所做的事情,但更加明确;你看到香肠是如何制作的。 :/
import types
import collections
class MyType(collections.MutableMapping):
def __init__(self, *args, **kwargs):
# do class specific stuff here
# create bound method per instance
self.keys = types.MethodType(collections.KeysView, self)
更好的是,我们可以在 __new__
中做到这一点,以更加确定继承 类 得到它:
import types
import collections
class MyType(collections.MutableMapping):
def __new__(cls, *args, **kwargs):
self = super(MyType, cls).__new__(cls)
# create bound method per instance
self.keys = types.MethodType(collections.KeysView, self)
return self
如果您不喜欢 types.MethodType
的相对无证性质,您可以使用 functools.partial
代替:
import functools
import collections
class MyType(collections.MutableMapping):
def __new__(cls, *args, **kwargs):
self = super(MyType).__new__(cls)
# create bound method per instance
self.keys = functools.partial(collections.KeysView, self)
return self
注意: 对于 Python 2/3 兼容性,您应该 而不是 对 types.MethodType
使用第三个可选的 class
参数;它存在于 Python 2 中,但显然在 Python 3 中被删除。