[Python学习日记-68] 绑定方法与非绑定方法
简介
绑定方法
非绑定方法
绑定方法与非绑定方法的应用
简介
在之前我们学习类与对象的属性查找与绑定方法的时候就接触过绑定方法了,不过当时是简单的介绍了针对于对象的绑定方法,其实在类内部定义的函数分为两大类:绑定方法(bound method)和非绑定方法(unbound method),下面我们来展开介绍一下。
绑定方法
绑定方法是与特定对象关联的方法。当调用一个绑定方法时,该方法会自动将该对象作为第一个参数(这个参数通常被称为 self)传递给方法,从而让绑定方法可以访问和修改对象的属性。简单来说就是绑定给谁就应该由谁来调用,并且谁来调用就会把调用者当作第一个参数自动传入。
而绑定方法又分为两类:绑定到对象的方法和绑定到类的方法。
一、绑定到对象的方法
绑定到对象的方法是我们最常见的绑定方法,在类当中没有被任何装饰器装饰的方法就是绑定到对象的方法,它有以下特点:
- 为对象量身定制
- 执行
对象 .boud_method()
时,自动将对象当作第一个参数传入 - 属于类的函数,类可以调用,但是必须按照函数的规则来,没有自动传值那么一说
二、绑定到类的方法
绑定到类的方法这个我们并没有接触过,在类当中用 @classmethod 装饰器装饰的方法就是绑定到类的方法,它有以下特点:
- 为类量身定制
- 执行
类 .boud_method()
时,自动将类当作第一个参数传入 - 绑定方法其实对象也可调用,但仍将类当作第一个参数传入
绑定到类的方法就是专门给类用的,但其实对象也可以调用,只不过自动传入的第一个参数仍然是类,也就是说这种调用是没有意义的,并且容易引起混淆,这也是 Python 的对象系统与其他面向对象语言对象系统的区别之一,例如 Smalltalk 和 Ruby 中,绑定到类的方法与绑定到对象的方法是严格区分开的。
非绑定方法
非绑定方法是与类关联的方法。它们不会自动接收一个对象作为参数,因此无法直接访问和修改对象的属性。这个在之前也没有接触过,在类中用 @staticmethod 装饰器装饰的方法就是非绑定方法,它不与类或对象绑定,类和对象都可以调用,但是没有自动传值那么一说,即需要手动传递一个对象作为参数。就是一个普通工具而已。
需要注意与绑定到对象的方法区分开来,绑定到对象的方法是最简单的,无须任何装饰器装饰的,但是它可不是普通的函数,对象调用时该方法可是会自动传值的,而非绑定方法则是不管谁来调用都没有自动传值这一说。
绑定方法与非绑定方法的应用
在前面了解完了绑定方法与非绑定方法的分类和特点之后,我们来看看到底应该怎么用,我们先建立一个 settings.py 来存储一些关于对象的设置参数,如下
# settings.py
# 存储的都是对象实例化时 __init__ 所需的参数
name = 'jove'
age = 18
sex = 'male'
下面来编写类,如下
import settings
import hashlib
import time
class People:
def __init__(self, name, age, sex):
self.id = self.create_id()
self.name = name
self.age = age
self.sex = sex
# 采用那种方法一定是根据函数体的逻辑来决定的
# 绑定到对象的方法
def tell_info(self):
print('Name:%s Age:%s Sex:%s' % (self.name, self.age, self.sex))
# 绑定到类的方法
@classmethod
def from_conf(cls):
obj = cls(
settings.name,
settings.age,
settings.sex
)
return obj
# 非绑定方法
@staticmethod
def create_id():
m = hashlib.md5(str(time.time()).encode('utf-8'))
return m.hexdigest()
p = People('lucy', 20, 'female')
# 绑定给对象,就应该由对象来调用,自动将对象本身当作第一个参数传入
p.tell_info() # tell_info(p)
# 绑定给类,就应该由类来调用,自动将类本身当作第一个参数传入
p = People.from_conf()
p.tell_info()
# 非绑定方法,不与类或者对象绑定,谁都可以调用,没有自动传值一说
p1 = People('jove1',18,'male')
time.sleep(1)
p2 = People('jove2',28,'male')
time.sleep(1)
p3 = People('jove3',38,'male')
print(p1.id)
print(p2.id)
print(p3.id)
代码输出如下:
总的来说,绑定方法与非绑定方法使用时若类中需要一个功能,该功能的实现代码中需要引用对象则将其定义成对象方法;该功能需要引用类则将其定义成类方法;该功能无需引用类或对象则将其定义成静态方法。