关于类实例化的问题

2017-07-04 18:36:27 +08:00
 saximi
类实例化成对象时,首先应该是调用类中的__call__函数,在__call__函数中先用__new__方法为对象分配内存空间,然后再在__call__函数中调用__init__方法初始化对象。如果这么理解没错的话,是否可以自己来实现类中的__call__函数,达到覆盖默认函数的目的呢?
但是我在网上看到这段说明以及相关代码的运行结果,觉得不理解,恳请指点!

代码定义了 Foo 类,但又为 Foo 定义了一个 __call__方法,
资料上说这时 Foo(*args, **kwargs) 实例化对象时并不等于 Foo.__call__(*args, **kwargs):

>>> class Foo:
... def __call__(self):
... print('running __call__')
...

>>> Foo()
<__main__.Foo object at 0x000000000227ABE0>

>>> Foo.__call__()
Traceback (most recent call last):
File "", line 1, in
TypeError: __call__() missing 1 required positional argument: 'self'
In this case, __call__ is used to call instances of the class :

>>> Foo()()
running __call__
1733 次点击
所在节点    Python
4 条回复
fffflyfish
2017-07-04 20:55:56 +08:00
类实例化成对象,不是首先应该调用构造函数吗,__call__是针对已经实例化的对象作为函数的时候用的吧
![屏幕快照 2017-07-04 下午 8.55.25.png]( https://ooo.0o0.ooo/2017/07/04/595b904e49327.png)
tonychow
2017-07-05 00:12:51 +08:00
__call__(self[, args...]) 方法是实例方法而非类方法

ref https://docs.python.org/2/reference/datamodel.html#emulating-callable-objects
saximi
2017-07-05 19:42:20 +08:00
@tonychow 谢谢,我是在 http://www.jianshu.com/p/f63ad9d550f1 这篇文章中看到对于常规类的实例化步骤描述为大致等同如下:

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

__new__方法为对象分配了内存空间,构建它为一个“空"对象然后__init__方法被调用来初始化它。总的来说:

Foo(*args, **kwargs)等价于 Foo.__call__(*args, **kwargs)

既然 Foo 是一个 type 的实例,Foo.__call__(*args, **kwargs)实际调用的是 type.__call__(Foo, *args, **kwargs)

type.__call__(Foo, *args, **kwargs)调用 type.__new__(Foo, *args, **kwargs),然后返回一个对象。
obj 随后通过调用 obj.__init__(*args, **kwargs)被初始化。
obj 被返回。


我帖子所提的问题也是这个网址在文章末尾提出的关注点,我就是不明白要怎么理解
saximi
2017-07-06 22:09:25 +08:00
自己顶一下,恳请大家指点,感谢啊!!!!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/373020

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX