python面向对象之绑定与非绑定方法
绑定方法与非绑定方法
在类中正常定义的函数默认是绑定到对象的,而为某个函数加上装饰器@classmethod后,该函数就绑定到了类。
绑定方法
绑定方法:绑定给某个目标(类或对象)的方法 --- 动态方法
【1】绑定给对象的方法(默认)
class MyClass: # 类的属性有两种:一种是数据属性 一种是函数属性
# 【1】数据属性
school = 'B站大学'
# 【2】函数属性
def __init__(self, name):
self.name = name
def print_name(self):
print(self)
print(self.name)
(1)实例化得到对象,对象调用对象的绑定方法
obj = MyClass('python')
obj.print_name() # 这里调用print_x方法时,obj被自动传递为第一个参数
# 实例方法self的内容为:<__main__.MyClass object at 0x0000022450915990>
# python
在上面的例子中,print_x是一个绑定方法。当我们通过obj.print_x()调用这个方法时,obj会自动作为第一个参数传递给print_x方法,所以print_x可以访问obj.x属性。
(2) 类调用对象的绑定方法
如果是类调用对象的绑定方法,那么就需要将对象作为参数传进去
Myclass.print_name(obj)
(3) 为什么一个类的实例方法绑定到不同的实例对象,他们就是不同的实例方法?
因为他们地址不同
# 实例化对象
obj1 = MyClass('python')
obj2 = MyClass('linux')
# 获取类的实例方法的地址
print(id(MyClass.print_name))
# 查看绑定到不同对象的实例方法的地址
print(id(obj1.print_name))
print(id(obj2.print_name))
# 地址均不同
# 2140485556704
# 2140486430528
# 2140486430336
总结:
对象调用绑定给对象的方法,不需要传额外的参数,直接能调用执行
类调用绑定给对象的方法,第一个位置参数必须是实例化得到的对象,加其他可能传入的额外的参数
【2】绑定给类的方法(@classmethod)
class MyClass: # # 类的属性有两种:一种是数据属性 一种是函数属性
# 【1】数据属性
school = 'B站大学'
# 【2】函数属性
def __init__(self, name):
self.name = name
def print_name(self):
print(self.name)
# 【3】函数属性 --- 绑定给类的方法
@classmethod # 装饰器的语法糖
def write(cls,name):
print(f' {name} 已经开课')
print(MyClass.write) # # 绑定到类的方法
# <bound method MyClass.write of <class '__main__.MyClass'>>
MyClass.write('python') # # 调用类方法,自动将类MySQL当作第一个参数传给cls
# python已经开课
总结:
绑定到类的方法就是专门给类用的,但其实对象也可以调用,只不过自动传入的第一个参数仍然是类,也就是说这种调用是没有意义的,并且容易引起混淆,这也是Python的对象系统与其他面向对象语言对象系统的区别之一,比如Smalltalk和Ruby中,绑定到类的方法与绑定到对象的方法是严格区分开的。
非绑定方法(@staticmethod)
为类中某个函数加上装饰器@staticmethod后,该函数就变成了非绑定方法,也称为静态方法。该方法不与类或对象绑定,类与对象都可以来调用它,但它就是一个普通函数而已,因而没有自动传值那么一说,但在调用非绑定方法时,需要手动传递实例或类对象作为参数。
class MyClass: # # 类的属性有两种:一种是数据属性 一种是函数属性
# 【1】数据属性
school = 'B站大学'
# 【2】函数属性
def __init__(self, name):
self.name = name
def print_name(self):
print(self.name)
# 【3】函数属性 --- 绑定给类的方法
@classmethod # 装饰器的语法糖
def write(cls, name):
print(f' {name} 已经开课')
# 【3】函数属性 --- 非绑定方法,本质上其实就是一个普普通通的函数
@staticmethod
def over(name):
print(f' {name} 已经结课')
(1)对象调用非绑定方法.不需要传额外的参数
obj = MyClass('python')
obj.over('python')
(2)类调用非绑定方法.不需要传额外的参数
MyClass.over('python')
总结:
对象调用非绑定方法,不需要传额外的参数
类调用非绑定方法,不需要传额外的参数
总结
总结来说,绑定方法会自动将对象作为第一个参数进行传递,而非绑定方法不会自动传递对象作为参数。
绑定方法可以直接访问对象的属性和方法,而非绑定方法则需要手动传递对象作为参数才能访问对象的属性和方法。