📜  Python中的绑定、未绑定和静态方法

📅  最后修改于: 2022-05-13 01:54:49.540000             🧑  作者: Mango

Python中的绑定、未绑定和静态方法

Python中的方法与函数类似,只是它附加到一个对象。这些方法是在对象上调用的,它可能会更改该对象。这些方法可以是 Bound、Unbound 或 Static 方法。静态方法是 Unbound 方法的一种。下面将详细解释这些类型。

绑定方法

如果函数是类的属性并且通过实例访问,则它们称为绑定方法。绑定方法是将“ self ”作为第一个参数的方法。由于这些依赖于类的实例,因此它们也称为实例方法。

需要这些绑定方法

类中的方法至少需要一个参数。为了使它们成为零参数方法,必须使用“ decorators ”。一个类的不同实例具有与之关联的不同值。

例如,如果有一个类“Fruits”,那么像 apple、orange、mango 这样的实例都是可能的。每个实例可能有不同的大小、颜色、味道和营养。因此,要更改特定实例的任何值,该方法必须将“self”作为参数,以允许它仅更改其属性。

例子:

class sample(object):
  
    # Static variable for object number
    objectNo = 0
  
    def __init__(self, name1):
  
        # variable to hold name
        self.name = name1
  
        # Increment static variable for each object
        sample.objectNo = sample.objectNo + 1
  
        # each object's unique number that can be
        # considered as ID
        self.objNumber = sample.objectNo
  
    def myFunc(self):
        print("My name is ", self.name, 
              "from object ", self.objNumber)
  
    def alterIt(self, newName):
        self.name = newName
  
    def myFunc2():
        print("I am not a bound method !!!")
  
  
# creating first instance of class sample        
samp1 = sample("A")
samp1.myFunc()
  
# unhide the line below to see the error
# samp1.myFunc2() #----------> error line
  
  
# creating second instance of class sample    
samp2 = sample("B")
samp2.myFunc()
samp2.alterIt("C")
samp2.myFunc()
samp1.myFunc()

输出:

My name is  A from object  1
My name is  B from object  2
My name is  C from object  2
My name is  A from object  1

在上面的示例中,创建了两个实例,即 samp1 和 samp2。请注意,当函数alterIt()应用于第二个实例时,仅更改该特定实例的值。行samp1.myFunc()将扩展为sample.myFunc(samp1) 。对于此方法,不需要传递显式参数。实例 samp1 将作为参数传递给 myFunc()。行samp1.myFunc2()将产生错误:

Traceback (most recent call last):
  File "/home/4f130d34a1a72402e0d26bab554c2cf6.py", line 26, in 
    samp1.myFunc2() #----------> error line
TypeError: myFunc2() takes 0 positional arguments but 1 was given

这意味着这个方法是未绑定的。它不接受任何实例作为参数。这些函数是未绑定函数。

未绑定方法和静态方法

没有类实例作为第一个参数的方法称为未绑定方法。从Python 3.0 开始,未绑定的方法已从该语言中删除。它们不受类的任何特定对象的限制。为了使myFunc2()方法在上面的类中工作,它应该变成一个静态方法

静态方法类似于类方法,但完全绑定到类而不是特定对象。使用类名访问它们。

需要将方法设为静态

并非所有方法都需要更改类的实例。它们可能服务于任何共同目的。方法也可以是效用函数。

例如,当我们需要使用某些数学函数时,我们使用内置类Math 。此类中的方法是静态的,因为它们与特定对象无关。他们做共同的动作。因此,每次都不是一种优化的写法:

math=Math()
math.ceil(5.23)

因此可以使用它们的类名作为Math.ceil(5.23)来简单地访问它们。

可以通过两种方式将方法设为静态:

  1. 使用静态方法()
  2. 使用装饰器

使用 staticmethod(): staticmethod()函数将要转换的函数作为其参数,并返回该函数的静态版本。静态函数对类一无所知,它只使用传递给它的参数。

例子:

class sample():
       
      def myFunc2(x):
     
             print("I am", x, "from the static method")
  
sample.myFunc2 = staticmethod(sample.myFunc2)
sample.myFunc2("A")

输出:

I am A from the static method

使用装饰器:这些是Python的功能,用于在编译时使用程序的另一部分来修改程序的一部分。可用于使方法静态的装饰器是

@staticmethod

这通知内置默认元类不要为此方法创建任何绑定方法。一旦在函数之前添加了这一行,就可以使用类名调用该函数。考虑我们遇到错误的 Bound 方法的示例。为了克服这个问题,它可以写成:

class sample(object):
  
    # Static variable for object number
    objectNo = 0
  
    def __init__(self, name1):
        # variable to hold name
        self.name = name1
  
        # Increment static variable for each object
        sample.objectNo = sample.objectNo + 1
  
        # each object's unique number that can be
        # considered as ID
        self.objNumber = sample.objectNo
  
    def myFunc(self):
        print("My name is ", self.name, 
              "from object ", self.objNumber)
  
    def alterIt(self, newName):
        self.name = newName
  
    # using decorator to make the method static
    @staticmethod
    def myFunc2():
        print("I am not a bound method !!!")
  
  
# creating first instance of class sample        
samp1 = sample("A")
samp1.myFunc()
  
  
sample.myFunc2() #----------> error line
  
  
# creating second instance of class sample    
samp2 = sample("B")
samp2.myFunc()
samp2.alterIt("C")
samp2.myFunc()
samp1.myFunc()

输出:

My name is  A from object  1
I am not a bound method !!!
My name is  B from object  2
My name is  C from object  2
My name is  A from object  1

在这里,行sample.myFunc2()运行没有任何错误,并且其中的 print() 运行良好,并给出了输出I is not a bound method!!!