- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我在Jupyter控制台运行代码(Python的版本是2.7.14
),
type(1)
Out[71]: int
type.__call__(1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-72-0ed097e2c413> in <module>()
----> 1 type.__call__(1)
TypeError: descriptor '__call__' requires a 'type' object but received a 'int'
我猜 type(...)
等同于 type.__call__(...)
但它似乎不是。所以我想知道:
type(1)
或 type(name, base, dict)
时,python 解释器做了什么?type.__call__(...)
?谢谢。
最佳答案
简短版本:type.__call__
可以解析为两个合理的东西:表示用于调用 type
本身的方法的绑定(bind)方法,或表示用于调用 type
实例的方法。您期待第一个结果,但实际得到的是第二个。
长版:
some_callable(thing)
通常等同于 some_callable.__call__(thing)
。例如,print(1)
等同于 print.__call__(1)
(只要您打开了 from __future__ import print_function
) :
>>> print(1)
1
>>> print.__call__(1)
1
type
是可调用的,type(thing)
会 等同于 type.__call__(thing)
,除了属性查找会遇到复杂情况。
在 type.__call__
属性查找期间,Python 在 type
及其父类(super class)(只是 object
)中搜索 __dict__
键 '__call__'
条目。 Python 还 搜索type
的类型和type
的类型的父类(super class)以查找这样的__dict__
条目。 (您可以在 type_getattro
中看到负责调用这些搜索的代码,这是处理类型属性查找的 C 函数。)因为 type
是它自己的类型,所以这两个搜索都找到 type .__dict__['__call__']
.
其中一个搜索优先。做出选择的方式,以及选择甚至重要的原因,是 descriptor protocol .如果第一次搜索成功,则描述符协议(protocol)将正常应用以查找类属性 (descriptor.__get__(None, cls)
);如果第二次搜索获胜,描述符协议(protocol)将正常应用以查找实例属性 (descriptor.__get__(instance, cls)
)。第二次搜索需要赢得 type.__call__(thing)
才能表现得像 type(thing)
,但只有 type.__dict__['__call__ ']
是一个数据描述符,但现在不是。
第一次搜索获胜。描述符协议(protocol)通常用于查找类属性,查找 type.__call__
的结果是 unbound 方法。它表示 type
实例的通用 __call__
方法,而不是 type
的 __call__
实例方法-as-类型实例。它需要被称为
type.__call__(type, 1)
等同于type(1)
。
毕竟,您可能想知道 type(thing)
如何在不遇到所有这些复杂情况的情况下工作。在语言语义上,Python 只在查找 type
的 __call__
方法调用它时才进行第二次搜索,所以第一次搜索无法取胜,因为它没有甚至不会发生。在实际实现方面,CPython 实际上根本不查找 __call__
方法;它查找type
的类型,转到__call__
对应的type
类型的C 级插槽,并调用the function it finds。 .对于在 Python 中实现的 __call__
方法,C 槽将包含一个查找和调用 Python 方法的函数,但对于在 C 中实现的 __call__
,C 槽包含__call__
直接实现。
关于python - type(1) 是否等同于 type.__call__(1)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52397650/
class Meta(type): def __call__(cls, *args, **kwargs): print 'Meta.__call__ called.'
一个非常简单的类不是可调用类型: >>> class myc: ... pass ... >>> c=myc() >>> callable(c) False 如何判断一个类是否有方法__cal
我想在 python 中实现单例模式,我喜欢 http://www.python-course.eu/python3_metaclasses.php 中描述的模式. class Singleton(t
根据我对 Python 面向对象编程的所有了解,如果一个类定义了 __call__ 方法,如果我们像函数调用一样使用该类的实例,该方法将被调用。例如: class Employee: def
Python 的神奇方法 __call__ 会在您尝试调用对象时被调用。 Cls()() 因此等于 Cls.__call__(Cls())。 函数是 Python 中的第一类对象,这意味着它们只是可调
在 python 中,您可以通过实现 __call__ 方法使实例可调用。例如 class Blah: def __call__(self): print "hello" ob
我需要在测试中修补当前日期时间。我正在使用这个解决方案: def _utcnow(): return datetime.datetime.utcnow() def utcnow():
我知道类中的 __call__ 方法是在调用类的实例时触发的。但是,我不知道什么时候可以使用这种特殊方法,因为可以简单地创建一个新方法并执行在 __call__ 方法中完成的相同操作,而不是调用实例,
本节再介绍 Python 类中一个非常特殊的实例方法,即 __call__()。该方法的功能类似于在类中重载 () 运算符,使得类实例对象可以像调用普通函数那样,以“对象名()”的形式使用。 举个例子
这个问题在这里已经有了答案: Overriding special methods on an instance (5 个回答) 关闭2年前。 我需要更改给定对象的 __call__ 方法的行为。天真
class Method(object): def __call__(self): #how could I get the App instance here?
我试图理解下面的代码。 class Chain(object): def __init__(self, path=''): self._path = path def
我正在浏览 Daniel Nouri 的 tutorial关于使用 CNN 的面部识别,我遇到了一些我不理解的代码。 Daniel 正在定义一个在网络训练期间每次迭代结束时调用的类,它将决定训练是否应
Python 的可调用对象是具有 __call__ 方法的对象。它们大部分时间是函数,但也可能是类实例。 但是函数确实有一个 __call__ 方法。因此,一个 __call__ 方法也有一个 __c
我正在用 Python 编写单元测试,我想创建一个模拟函数,在调用时返回另一个模拟(由我指定)。 这是我尝试过的: my_mock = Mock() fn = Mock() fn.__call__ =
以此为例: class Foo(object): def __init__(self, msg): self._msg = msg def __call__(self):
考虑以下代码: class MyCustomDescriptor: def __init__(self,foo): self._foo = foo def __call
我正在测试 simpleTAL 模板库,它使用 callable 来测试传入模板的对象是否为函数。 callable 的定义是说如果一个对象包含魔法方法__call__,那么它就是可调用的。另见 Wh
我在 python2.7 中使用 tkinter。我想要做的就是在一个类中绘制一个 Canvas ,然后在另一个类中绘制一个 Canvas ,该类将在 Canvas 周围移动一个正方形。但出于某种原因
我试图在运行时定义 __call__ dunder 方法,但没有成功。代码如下: class Struct: pass result=Struct() dictionary={'a':5,'b
我是一名优秀的程序员,十分优秀!