Python 面向对象之绑定和非绑定方法
【一】序言
- 在Python类的成员中分为两类:一个是属性,另一个就是方法(就是定义的函数)
- 方法又分为两大类:绑定方法(动态方法)和非绑定方法(静态方法)
- 从名字上就能知道他们的区别,一个绑定了另一个没有绑定,那么接下来就将具体的讲讲
【二】绑定方法
- 绑定方法就是指与特定对象关联的方法
- 它也被分为两大类:绑定给对象的实例方法(对象方法)和绑定给类的类方法
【1】实例方法(对象方法)
(1)概念
-
绑定到对象上的方法,基本都是为对象服务
-
没有被任何装饰器装饰的方法
-
第一个参数时
self
,实例本身 -
当对象调用实例方法时(
对象.实例方法()
),自动将对象当作第一个参数传入 -
当类调用实例方法时(
类.实例方法(类())
),需要手动传入一个实例 -
一个类的实例方法绑定到不同的对象就是不同的实例方法,内存地址各不相同。
(2)代码解释
# 绑定给对象,为对象服务
# 没有任何装饰器
class Plant:
plant_owner = "戴夫"
# 没有装饰器
# 这个也是实例方法
def __init__(self, name, health, attack_value):
self.name = name
self.health = health
self.attack_value = attack_value
# 没有装饰器
def introduce(self):
print(f"""
我是{self.name}
我的生命值为{self.health},
我的攻击力为{self.attack_value},
我的主人是{self.plant_owner}
""")
# 实例对象
pee_shooter = Plant(name="豌豆射手", health=80, attack_value=10)
# 为对象服务
pee_shooter.introduce()
# 我是豌豆射手
# 我的生命值为80,
# 我的攻击力为10,
# 我的主人是戴夫
# 当对象调用实例方法时,自动将对象当作第一个参数传入
# 当类调用实例方法时,需要手动传入一个实例
# 实例化对象
pee_shooter = Plant(name="豌豆射手", health=80, attack_value=10)
# 对象调用实例方法
pee_shooter.introduce_self()
# 实例方法self的内容为:
# 类调用实例方法,需要手动传入一个实例
Plant.introduce_self(pee_shooter)
# 一个类的实例方法绑定到不同的实例对象,他们就是不同的实例方法,因为他们地址不同
# 实例化对象
sunflower = Plant(name="向日葵", health=100, attack_value=0)
pee_shooter = Plant(name="豌豆射手", health=80, attack_value=10)
# 获取类的实例方法的地址
print(id(Plant.introduce))
# 查看绑定到不同对象的实例方法的地址
print(id(sunflower.introduce))
print(id(pee_shooter.introduce))
# 1847514406128 # 地址都不一样
# 1847514372160
# 1847514372096
【2】类方法
(1)概念
-
绑定到类上的方法,基本都是为类服务
-
用
classmethod
装饰器装饰的方法 -
第一个参数时
cls
,类本身 -
当类调用类方法时(
类.实例方法()
),自动将类当作第一个参数传入 -
当对象调用实例方法时(
对象.实例方法()
),自动将对象的类当作第一个参数传入
(2)代码解释
# 绑定到类上,为类服务
# 用classmethod装饰器装饰
# 第一个参数是cls
class Plant:
plant_owner = "戴夫"
plant_rival 服务器托管网= "僵尸博士"
def __init__(self, name, health, attack_value):
self.name = name
self.health = health
self.attack_value = attack_value
# 用classmethod装饰器装饰
# 第一个参数是cls
@classmethod
def introduce_rival(cls):
print(f"{cls.__name__}的对手是{cls.__dict__['plant_rival']}")
# 为类服务
Plant.introduce_rival()
# 无论是类还是实例调用实例方法,都会自动传入类给cls参数
# 一个类的实例方法绑定到不同的实例对象,他们就是不同的实例方法,因为他们地址不同
class Plant:
plant_owner = "戴夫"
plant_rival = "僵尸博士"
def服务器托管网 __init__(self, name, health, attack_value):
self.name = name
self.health = health
self.attack_value = attack_value
@classmethod
def introduce_rival(cls):
print(f"{cls.__name__}的对手是{cls.__dict__['plant_rival']}")
# 类调用类方法
print(id(Plant.introduce_rival))
Plant.introduce_rival()
# 1693174119296
# Plant的对手是僵尸博士
# 实例化对象
pee_shooter = Plant("豌豆射手", 80,10)
# 实例对象调用类方法
print(id(pee_shooter.introduce_rival))
pee_shooter.introduce_rival()
# 1693174119296
# Plant的对手是僵尸博士
- 可以看到地址相同,即是同一个内容
【三】非绑定方法
- 非绑定方法就是既没有绑定给类也没有绑定给对象的方法,谁也没有绑定
【1】非绑定方法
(1)概念
-
不和类也不和对象进行绑定
-
用
staticmethod
装饰器装饰的方法 -
就是一个普普通通的方法(函数),没有特殊的参数
-
可以在类的外部直接调用(类.非绑定方法())(对象.非绑定方法())
(2)代码解释
class Plant:
plant_owner = "戴夫"
plant_rival = "僵尸博士"
def __init__(self, name, health, attack_value):
self.name = name
self.health = health
self.attack_value = attack_value
@staticmethod
def static_method():
print("这是植物类的静态方法")
# 实例化对象
pee_shooter = Plant(name="豌豆射手", health=80, attack_value=10)
# 实例访问
print(id(pee_shooter.static_method))
pee_shooter.static_method()
# 2055404428960
# 这是植物类的静态方法
# 类访问
print(id(Plant.static_method))
Plant.static_method()
# 2055404428960 # 地址相同
# 这是植物类的静态方法
- 可以看到地址相同,即是同一个内容
【四】总结
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
开源项目地址:https://gitee.com/easyxaf/jsplumb-navigator 前言 jsPlumb可用于连接DOM元素,它不依赖框架,所以与主流框架都可以无缝的集成。但比较遗憾的是社区版中没有平移、缩放等功能,如果用它来开发工作流等项目…