- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
>> type(B.__dic-6ren">
今天我定义了一个类来测试接下来会发生什么:
class B(object):
def p(self):
print("p")
后来我这样做了:
>>> type(B.__dict__['p'])
<type 'function'>
>>> type(B.p)
<type 'instancemethod'>
那么,为什么? B.p
和 B.__dict__['p']
不是同一个对象吗?
当我尝试这个时,我的惊讶增加了:
>>> B.__dict__['p']
<function p at 0x3d2bc80>
>>> type(B.__dict__['p'])
<type 'function'>
好的,到目前为止一切顺利,类型在两个结果function
中,但是当我尝试时:
>>> B.p
<unbound method B.p>
>>> type(B.p)
<type 'instancemethod'>
什么?!,为什么? 未绑定(bind)方法
和instancemethod
?那些是一样的吗?为什么有两个不同的名字?
嗯,看来python充满了惊喜!
这是我正在使用的python:
Python 2.7.4 (default, Sep 26 2013, 03:20:26)
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
最佳答案
这是一个非常好的问题。
清除一些东西:
B.p
)访问方法名称时,它被称为 unbound。B().p
)访问该方法,则称该方法是 bound。bound 和 unbound 的主要区别在于,如果 bound,第一个参数将隐含地是 调用的实例 类。这就是为什么我们必须在定义每个方法时添加 self
作为第一个参数。当unbound时,你必须明确地传递你想要应用方法逻辑的类的实例。
例如:
class B(object):
def foo(self):
print 'ok'
>>>B().foo()
ok
>>>B.foo()
Exception, missing an argument.
>>>B.foo(B())
ok
这是bound和unbound的基本解释。现在关于 __dict__
的怪异之处。 Python 中的任何对象都可以定义 __get__
和 __set__
方法,当它们是类中的属性时,它们控制对它们的访问。这些被称为描述符。
简单来说,当你通过实例或类访问一个类的属性(属性)时,Python 不会直接返回对象,而是调用 __get__
或 __set__
方法返回一个方便使用的对象。
Python 中的函数会覆盖此 __get__
方法。因此,当您发出 B.foo
或 B().foo
时,它会返回一个 instancemethod
类型,它是 function< 的包装器
类型(将 self
作为第一个参数隐式传递的包装器)。当您通过原始类的字典访问该函数时,不会调用 __get__
因为您没有将它们作为类的属性进行访问,因此返回值为 raw 函数。
关于这个话题有很多话要说,我试图对这样一个聪明的话题给出一个非常简单的答案。您可以在 Guido 的博客文章 The Inside Story on New-Style Classes 上找到权威信息,非常推荐。
更新:关于您的最后一个示例:
>>> B.p
<unbound method B.p>
>>> type(B.p)
<type 'instancemethod'>
请注意,在 Python 的解释器中,>>>B.p
实际上并不打印对象的类型,而是打印对象的 __repr__
方法。您可以通过执行 >>>print B.p.__repr__()
来检查它并看到它的相同结果:)
Python 充满了间接和委托(delegate),这就是它如此灵活的原因。
希望这能澄清一点。
关于python - 实例方法还是函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20683985/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!