types.MethodType
期望什么参数以及它返回什么?
https://docs.python.org/3.6/library/types.html没有详细说明:
types.MethodType
用户定义的类实例的方法类型。
例如,来自https://docs.python.org/3.6/howto/descriptor.html
为了支持方法调用,函数包括
__get__()
方法 属性访问期间的绑定方法。这意味着所有功能 是非数据描述符,它返回绑定或未绑定的方法 取决于它们是从对象还是类中调用的。在纯粹 python,它的工作原理如下:class Function(object): . . . def __get__(self, obj, objtype=None): "Simulate func_descr_get() in Objects/funcobject.c" if obj is None: return self return types.MethodType(self, obj)
self
的第一个参数types.MethodType
必须是可调用对象吗?换句话说,班级Function
必须是可调用类型,即必须Function
方法__call__
吗?
如果self
是可调用对象,是否需要至少一个参数?
types.MethodType(self, obj)
是否意味着将obj
作为可调用对象self
的第一个参数,即将self
与obj
进行合并?
types.MethodType(self, obj)
如何创建并返回types.MethodType
的实例?
感谢。
答案 0 :(得分:2)
通常,您不需要自己创建types.MethodType
的实例。而是在访问类实例上的方法时会自动获得一个。
例如,如果我们创建一个类,创建它的一个实例,然后访问该实例上的一个方法(不调用它),我们将获得一个types.MethodType
的实例:
import types
class Foo:
def bar(self):
pass
foo = Foo()
method = foo.bar
print(type(method) == types.MethodType) # prints True
您在问题中摘录的代码试图显示这种情况通常如何发生。尽管您可以可以,但通常不必自己做这件事。例如,要创建与上述types.MethodType
等效的method
的另一个实例,我们可以这样做:
method_manual = types.MethodType(Foo.bar, foo)
MethodType
的第一个参数是可调用对象(通常是一个函数,但可以是其他东西,例如您正在阅读的示例中的Function
类的实例)。第二个参数是我们将函数绑定到什么。当您调用方法对象(例如method()
)时,绑定的对象将作为第一个参数传递到函数中。
通常,方法绑定到的对象是一个实例,尽管它可以是其他实例。例如,一个装饰classmethod
的函数将绑定到被调用的类,而不是实例。这是一个示例(自动将方法绑定到类,然后自己手动完成):
class Foo2:
@classmethod
def baz(cls):
pass
foo2 = Foo2()
method2 = Foo2.baz
method2_via_an_instance = foo2.baz
method2_manual = types.MethodType(method2.__func__, Foo2)
所有三个method2
前缀变量的工作方式完全相同(当您调用它们时,它们都将以baz
作为Foo2
参数调用cls
)。这次关于手动方法的唯一不便之处是,如果没有获取绑定方法就很难获得原始的baz
函数,因此我将其从其他绑定方法对象之一中剔除了。
最后一点:名称types.MethodType
是用于绑定方法的内部类型的别名,否则它没有可访问的名称。与许多类不同,实例的repr
不是重新创建实例的表达式(它类似于"<bound method Foo.bar of <__main__.Foo object at 0x0000...>>"
)。该类型的repr
也不是访问该类型所依据的有效名称(repr
是"method"
)。
答案 1 :(得分:1)
types.MethodType的第一个参数self必须是可调用对象吗? 换句话说,Function类必须是可调用的类型,即must 函数有方法
__call__
吗?
是
如果self是一个可调用对象,它是否至少接受一个参数?
取决于
types.MethodType(self,obj)是否意味着将obj作为第一个参数 到可调用对象的self,即使用obj进行currying self?
是
types.MethodType(self,obj)如何创建并返回一个实例 类型。方法类型?
它不是那样工作的。
代码
class Function(object):
. . .
def __get__(self, obj, objtype=None):
"Simulate func_descr_get() in Objects/funcobject.c"
if obj is None:
return self
return types.MethodType(self, obj)
如丹尼尔(Daniel)所说,主要是为了演示
为支持方法调用,函数包括
__get__()
方法,用于 属性访问期间的绑定方法。这意味着所有功能 是返回绑定或未绑定方法的非数据描述符 取决于是从对象还是从类调用它们。纯属 python,它是这样的:
当types.MethodType()
具有Function
时,object
起作用。
if obj is None
将是False
这就是某种对象的方法。绑定方法。
它解释了Python语法如何工作。作为功能,可以在 以下两种方式。
some_func_()
或some_class.some_func()
https://docs.python.org/3.6/howto/descriptor.html#invoking-descriptors的前一部分已解释。
对于对象,机器位于
object.__getattribute__()
中 将b.x
转换为type(b).__dict__['x'].__get__(b, type(b))
。的 通过提供数据的优先级链来实现 描述符优先于实例变量,实例变量 优先于非数据描述符,并将最低优先级分配给__getattr__()
(如果提供)。
这是一些演示代码
>>> import types
>>> types.MethodType
<type 'instancemethod'>
>>> def a(self):
... print(1)
...
>>> class B:
... pass
...
>>> types.MethodType(a,B)
<bound method ?.a of <class __main__.B at 0x7f4d3d5aa598>>
>>> B.t = types.MethodType(a,B)
>>> B.t()
1
>>> def s():
... print(3)
...
>>> B.r = types.MethodType(s,B)
>>> B.r
<bound method ?.s of <class __main__.B at 0x7f4d3d5aa598>>
>>> B.r()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: s() takes no arguments (1 given)
另请参见dynamically adding callable to class as instance "method"
答案 2 :(得分:1)
文档说明不多,但您可以随时查看其源代码。 MethodType 构造函数的签名是:
def __init__(self, func: Callable[..., Any], obj: object) -> None: ...
它接受一个可调用对象和对象,并返回 None。
MethodType 可用于向对象添加实例方法,而不是函数;这是一个例子:
from types import MethodType
class MyClass:
language = 'Python'
# a function is bound to obj1
obj1 = MyClass()
obj1.say_hello = lambda: 'Hello World!'
print(type(obj1.say_hello)) # type is class 'function'
obj1.say_hello()
# a method is bound to obj2
obj2 = MyClass()
# this is used to bind a "method" to a specific object obj2, rather than a function
obj2.say_hello = MethodType(lambda self: f'Hello {self.language}!', obj2)
print(type(obj2.say_hello)) # type is class 'method'
obj2.say_hello()
答案 3 :(得分:0)
这不是你打算过的东西。与types
模块中的大多数类一样,它与现有对象的比较更多(例如在isinstance
中)。