python tips:类的绑定方法(bound)和非绑定方法(unbound)

Posted luoheng23

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python tips:类的绑定方法(bound)和非绑定方法(unbound)相关的知识,希望对你有一定的参考价值。

类属性只有类及其实例能够访问,可以理解为一个独立的命名空间。

Python中类属性的引用方式有两种:

1. 通过类的实例进行属性引用,称为绑定方法(bound method),可以理解为方法与实例绑定在一起。

2. 通过类进行属性引用,称为非绑定方法(unbound method),方法没有与实例绑定。

在绑定方法中,为了与实例绑定,Python自动将实例作为方法的第一个参数,而非绑定方法则表现的像普通函数,和普通函数的区别在于它只能通过类来访问。

两种引用方式:

 1 class A:
 2     def test1(self):
 3         print(self)
 4 
 5 def main():
 6     a = A()
 7     a.test1()
 8     A.test1(a)
 9     A.test1(2)
10 
11 if __name__ == "__main__":
12     main()

输出结果:

1 <__main__.A object at 0x00000212C48D5908>
2 <__main__.A object at 0x00000212C48D5908>
3 2

上述代码中,类A有一个test1方法。两种引用方式说明如下:

1. 通过实例a来引用方法时,python自动将a作为第一个参数(self)传给方法test1。

2. 通过类来直接引用时,需要显式传给test1一个self参数,但是这个参数并不要求一定要是类的实例,传入其他值亦可(上述代码中传入的是2)。

引用方式的问题与优点:

 1 class A:
 2     def test2():
 3         print("hello")
 4     
 5     def test3(solf):
 6         print(solf)
 7 
 8 class B:
 9     pass
10 
11 def main():
12     a = A()
13     try:
14         a.test2()
15     except Exception as e:
16         print(e)
17     b = B()
18     A.test3(b)
19 
20 if __name__ == "__main__":
21     main()

输出结果:

1 test2() takes 0 positional arguments but 1 was given
2 <__main__.B object at 0x000001DFE1AC7898>

由于实例引用会隐式传入实例作为方法的第一个参数,所以当类的方法不接受参数的时候,使用实例就无法调用该方法。

类引用的显式传参没有要求,所以可以将A类的方法作用于B上。

类方法(classmethod)和静态方法(staticmethod):

 1 class A:
 2     @classmethod
 3     def test4(self):
 4         print(f"classmethod: self")
 5     
 6     @staticmethod
 7     def test5(self):
 8         print(f"staticmethod: self")
 9 
10 def main():
11     a = A()
12     a.test4()
13     A.test4()
14     a.test5(2)
15     A.test5(2)
16 
17 
18 if __name__ == "__main__":
19     main()

输出结果:

classmethod: <class __main__.A>
classmethod: <class __main__.A>
staticmethod: 2
staticmethod: 2

类方法和静态方法使用装饰器实现,和普通的方法有所区别。

从作用上看:

1. 类方法是只与类相关,而与类的实例无关的方法。

2. 静态方法是与类和实例都无关的方法。

从实现上看:

1. 类方法和静态方法统一了实例引用和类引用,两者都能通过两种引用方式调用。

2. 类方法永远隐式地使第一个传入的参数为类,静态方法所有参数都需要显示传入。

总结:

1. 类属性引用有两种,分为实例引用和类引用,对于方法属性,前者隐式传入实例作为第一个参数,后者类似于普通函数

2. self和cls是约定的实例和类的名称表示,并无强制性含义,类引用时可以传入任意值而不一定是类实例

3. 类方法与静态方法统一了两种引用方式,前者永远隐式传入类作为第一个参数,后者所有参数都需要显示传入。

以上是关于python tips:类的绑定方法(bound)和非绑定方法(unbound)的主要内容,如果未能解决你的问题,请参考以下文章

python tips:类的动态绑定

Python方法绑定——Unbound/Bound method object的一些梳理

python tips:类与实例的属性问题

10 绑定方法与非绑定方法

全面解析python类的绑定方法与非绑定方法

python 课堂15 面向对象3 内部方法,类的定制