【问题标题】:calling a function from class vs object in python从python中的类vs对象调用函数
【发布时间】:2018-10-25 00:36:39
【问题描述】:

我实际上是在浏览descriptors python 文档并遇到了这个例子

>>> class D(object):
     def f(self, x):
          return x

>>> d = D()
>>> D.__dict__['f'] # Stored internally as a function
<function f at 0x00C45070>
>>> id(D.__dict__['f']) # Memory location
49294384
>>> D.f             # Get from a class becomes an unbound method
<unbound method D.f>
>>> id(D.f )
48549440
>>> d.f             # Get from an instance becomes a bound method
<bound method D.f of <__main__.D object at 0x00B18C90>>
>>> id(d.f)
48549440

所以从上面的代码中,我了解到python将一个类的function definition/declaration作为一个单独的对象存储在类__dict__变量内部,当我们直接使用__dict__变量访问时,它的内存位置为49294384

但是为什么当通过Class or Object? 访问时,它显示为具有不同memory location 48549440 的不同函数/方法对象,例如D.f and d.f

当我们使用__dict__ 变量访问时,它不应该引用同一个对象吗?如果有,为什么?

【问题讨论】:

  • 您的代码来自 Python 2,但您链接到的文档是 Python 3。Python 3 中不再存在“未绑定方法”。
  • @DanielRoseman,很抱歉,我使用的是 Python 2.7,但即使文档中的代码也是一样的

标签: python function class object


【解决方案1】:

xtofi 解释了描述符对象(未绑定)和绑定方法之间的区别。

我认为缺少的部分是绑定的方法没有保存在内存中,它们实际上是在每次访问它们时创建的。 (你可能得到相同的内存位置,但它不是同一个对象)。

为什么? 因为每次调用描述符都可能导致不同的行为。这是一个解释这个想法的例子。

class A(object):
    i = 'a'

    @property
    def name(self):
        if A.i == 'a':
            return self.fa()
        else:
            return self.fb()

    def fa(self):
        print 'one function'

    def fb(self):
        print 'another function'

在 A 的实例上调用函数 name 会导致不同的函数调用。

【讨论】:

    【解决方案2】:

    D.f 是一个接受一个参数的函数 (self)

    x = D.f
    x(d)
    

    d.f 是一个“绑定方法”,即已经填写了self 参数的函数。你可以说

    x = d.f
    x()
    

    因此它不能与D.f 相同,并且必须位于不同的位置。

    【讨论】:

    • 如果您查看我的示例,当我将函数作为属性访问时,两种方式的内存位置 D.f and d.f 是相同的,我对此感到困惑,那是什么行为?
    • id 是否与“内存位置”相同?
    • 没错,当我提到内存位置时,它是 id
    • 表达式d.f 生成一个临时对象。多次调用它可能会导致不同的结果(但内存可能会被重用)。例如,试试[id(x) for x in (d.f, d.f, D.f, D.f)]
    猜你喜欢
    • 1970-01-01
    • 2013-07-05
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多