Python绑定,未绑定和静态方法

示例

Python 3中删除了绑定和非绑定方法的概念。在Python 3中,当您在类中声明方法时,您正在使用def关键字,从而创建了一个函数对象。这是一个常规函数,周围的类用作其命名空间。在下面的示例中,我们f在class中声明method A,它成为一个函数A.f:

Python 3.x 3.0
class A(object):

    def f(self, x):

        return 2 * x

A.f

# <functionA.fat ...>  (in Python 3.x)

在Python 2中,行为有所不同:类中的函数对象被类型为的对象隐式替换,这些对象instancemethod被称为未绑定方法,因为它们未绑定到任何特定的类实例。可以使用.__func__属性访问基础功能。

Python 2.x 2.3
A.f

# <unbound method A.f>   (in Python 2.x)

A.f.__class__

# <type 'instancemethod'>

A.f.__func__

# <function f at ...>

后一种行为通过检查得到了证实-方法在Python 3中被视为函数,而在Python 2中则保持了区别。

Python 3.x 3.0
import inspect

inspect.isfunction(A.f)

# 真正

inspect.ismethod(A.f)

# 假

Python 2.x 2.3
import inspect

inspect.isfunction(A.f)

# 假

inspect.ismethod(A.f)

# 真正


在两个版本的Python中A.f,只要您将class的实例A作为第一个参数传递,就可以直接调用函数/方法。

A.f(1, 7)

# Python 2:TypeError:未绑定方法f()必须使用

# 一个实例作为第一个参数(取而代之的是int实例) 

# 的Python 3:14   

a = A()

A.f(a, 20)

# Python 2 & 3: 40

现在假设a是class的实例A,那是a.f什么?好吧,从直觉上讲,这应该是f类的相同方法A,只是应该以某种方式“知道”它已应用于对象a–在Python中,这称为绑定到的方法a。

具体细节如下:编写会a.f调用的魔术__getattribute__方法a,该方法首先检查是否a有一个名为的属性f(没有),然后检查类A是否包含具有该名称的方法(有),并且创建一个新对象m类型的method,其具有的参考原始A.f中m.__func__,向对象的引用a中m.__self__。当将此对象作为函数调用时,它只需执行以下操作:m(...) => m.__func__(m.__self__, ...)。因此,将此对象称为绑定方法,因为在被调用时它知道提供绑定到的对象作为第一个参数。(这些内容在Python 2和3中的工作方式相同)。

a = A()

a.f

# <bound methodA.fof <__main__.A object at ...>>

a.f(2)

# 4

# 注意:绑定方法objecta.fis每次都会重新创建一次:

a.f isa.f # 假

# 作为性能优化,您可以将绑定方法存储在对象的

# __dict__,在这种情况下,方法对象将保持不变:

a.f = a.f

a.f isa.f # 真正

最后,Python有类方法和静态方法–特殊方法。类方法的工作方式与常规方法相同,除了在对象上调用它们时,它们将绑定到对象的而不是对象。这样。当您调用这样的绑定方法时,它将类的作为第一个参数传递。静态方法甚至更简单:它们根本不绑定任何内容,而只是返回基础函数而无需任何转换。m.__self__ = type(a)a

class D(object):

    multiplier = 2

    @classmethod

    def f(cls, x):

        returncls.multiplier* x

    @staticmethod

    def g(name):

        print("Hello, %s" % name)

D.f

# <bound methodtype.fof <class '__main__.D'>>

D.f(12)

# 24

D.g

# <functionD.gat ...>

D.g("world")

# 你好,世界

请注意,即使在实例上访问,类方法也已绑定到该类:

d = D()

d.multiplier = 1337

(D.multiplier, d.multiplier)

# (2,1337)

d.f

# <bound methodD.fof <class '__main__.D'>>

d.f(10)

# 20

值得注意的是,在最低层次上,函数,方法,静态方法等实际上是调用__get__,__set__和可选的__del__特殊方法的描述符。有关类方法和静态方法的更多详细信息:

  • Python中的@staticmethod和@classmethod有什么区别?

  • @classmethod和@staticmethod对初学者的意义?

以上是 Python绑定,未绑定和静态方法 的全部内容, 来源链接: utcz.com/z/315796.html

回到顶部