__call__ 或 __init__ 在这里打电话?不明白是哪个以及为什么
__call__ or __init__ called here? Don't undestand which and why
编辑:不幸的是,What is the difference between __init__ and __call__ in Python?
中没有回答
class OAuth2Bearer(requests.auth.AuthBase):
def __init__(self, api_key, access_token):
self._api_key = api_key
self._access_token = access_token
def __call__(self, r):
r.headers['Api-Key'] = self._api_key
r.headers['Authorization'] = "Bearer {}".format(self._access_token)
return r
#############
class AllegroAuthHandler(object):
def apply_auth(self):
return OAuth2Bearer(self._api_key, self.access_token) # what will happen here?
我读到了 __init__
和 __call__
,但我仍然不明白这段代码中发生了什么
我不明白:
1.) 会调用哪个方法,__init__
或 __call__
2.) 如果 __init__
,那么 __init__
不会 return 任何东西
3.)如果__call__
,则__call__
不能带两个参数调用
我认为应该调用 __init__
,因为我们有 X()
,而不是下面示例中的 x()
this answer:
x = X() # __init__ (constructor)
x() # __call__
我会说这两者都不是。
导致混淆的代码部分是
OAuth2Bearer(self._api_key, self.access_token)
你需要知道一件事:虽然 OAuth2Bearer
是 class 的名称,但它也是 class type
的对象(内置 class).所以当你写上面这行的时候,实际上调用的是
type.__call__()
如果您尝试以下代码,可以很容易地验证这一点:
print(repr(OAuth2Bearer.__call__))
它将return像这样:
<method-wrapper '__call__' of type object at 0x12345678>
type.__call__
做什么和 returns 在其他问题中有很好的介绍:它调用 OAuth2Bearer.__new__()
创建一个对象,然后用 obj.__init__()
初始化该对象,和 returns 那个对象.
你可以这样想OAuth2Bearer(self._api_key, self.access_token)
的内容(伪代码说明)
OAuth2Bearer(self._api_key, self.access_token):
obj = OAuth2Bearer.__new__(OAuth2Bearer, self._api_key, self.access_token)
obj.__init__()
return obj
__init__()
在与 Class
一起使用时被调用
__call__()
在与 Class
的对象一起使用时被调用
我相信 this 就是您要找的。
在 Python 中调用对象的行为由其类型 __call__
控制,因此:
OAuth2Bearer(args)
其实是这样的:
type(OAuth2Bearer).__call__(OAuth2Bearer, args)
OAuth2Bearer
的类型是什么,也称为 "metaclass"?如果不是 type
,则默认为 type
的子类(这由 Python 严格执行)。来自上面的link:
If we ignore error checking for a minute, then for regular class instantiation this is roughly equivalent to:
def __call__(obj_type, *args, **kwargs):
obj = obj_type.__new__(*args, **kwargs)
if obj is not None and issubclass(obj, obj_type):
obj.__init__(*args, **kwargs)
return obj
所以调用的结果就是object.__new__
传递给object.__init__
后的结果。 object.__new__
基本上只是为一个新对象分配 space 并且是这样做的唯一方法 AFAIK。要调用 OAuth2Bearer.__call__
,您必须调用实例:
OAuth2Bearer(init_args)(call_args)
编辑:不幸的是,What is the difference between __init__ and __call__ in Python?
中没有回答class OAuth2Bearer(requests.auth.AuthBase):
def __init__(self, api_key, access_token):
self._api_key = api_key
self._access_token = access_token
def __call__(self, r):
r.headers['Api-Key'] = self._api_key
r.headers['Authorization'] = "Bearer {}".format(self._access_token)
return r
#############
class AllegroAuthHandler(object):
def apply_auth(self):
return OAuth2Bearer(self._api_key, self.access_token) # what will happen here?
我读到了 __init__
和 __call__
,但我仍然不明白这段代码中发生了什么
我不明白:
1.) 会调用哪个方法,__init__
或 __call__
2.) 如果 __init__
,那么 __init__
不会 return 任何东西
3.)如果__call__
,则__call__
不能带两个参数调用
我认为应该调用 __init__
,因为我们有 X()
,而不是下面示例中的 x()
this answer:
x = X() # __init__ (constructor)
x() # __call__
我会说这两者都不是。
导致混淆的代码部分是
OAuth2Bearer(self._api_key, self.access_token)
你需要知道一件事:虽然 OAuth2Bearer
是 class 的名称,但它也是 class type
的对象(内置 class).所以当你写上面这行的时候,实际上调用的是
type.__call__()
如果您尝试以下代码,可以很容易地验证这一点:
print(repr(OAuth2Bearer.__call__))
它将return像这样:
<method-wrapper '__call__' of type object at 0x12345678>
type.__call__
做什么和 returns 在其他问题中有很好的介绍:它调用 OAuth2Bearer.__new__()
创建一个对象,然后用 obj.__init__()
初始化该对象,和 returns 那个对象.
你可以这样想OAuth2Bearer(self._api_key, self.access_token)
的内容(伪代码说明)
OAuth2Bearer(self._api_key, self.access_token):
obj = OAuth2Bearer.__new__(OAuth2Bearer, self._api_key, self.access_token)
obj.__init__()
return obj
__init__()
在与 Class
__call__()
在与 Class
我相信 this 就是您要找的。
在 Python 中调用对象的行为由其类型 __call__
控制,因此:
OAuth2Bearer(args)
其实是这样的:
type(OAuth2Bearer).__call__(OAuth2Bearer, args)
OAuth2Bearer
的类型是什么,也称为 "metaclass"?如果不是 type
,则默认为 type
的子类(这由 Python 严格执行)。来自上面的link:
If we ignore error checking for a minute, then for regular class instantiation this is roughly equivalent to:
def __call__(obj_type, *args, **kwargs):
obj = obj_type.__new__(*args, **kwargs)
if obj is not None and issubclass(obj, obj_type):
obj.__init__(*args, **kwargs)
return obj
所以调用的结果就是object.__new__
传递给object.__init__
后的结果。 object.__new__
基本上只是为一个新对象分配 space 并且是这样做的唯一方法 AFAIK。要调用 OAuth2Bearer.__call__
,您必须调用实例:
OAuth2Bearer(init_args)(call_args)