Python学习笔记
面向对象(2)
实例方法与自动绑定
- 使用对象调用实例方法时,python会自动绑定方法的第一个参数(通常建议将该参数命名为self)
- 根据第一个参数出现位置的不同,第一个参数所绑定的对象略有区别。但是总之,方法中的self总是代表该方法的调用者。实例方法的第一个self不需要传入,由系统自动绑定,总是绑定到方法调用者。
- 在构造方法中引用该构造方法正在初始化的对象。
- 在普通实例方法中引用调用该方法的对象
class User:
def __init__(self, name = "tiger"):
self.name = name
def info(self):
print(self)
print(self.name)
u = User()
print(u.name)
u2 = User("scott")
print(u2.name)
print(u2)
u2.info()
u1 = User()
u1.info()
- 注意:当python的一个方法调用另一个方法时,不可以省略self;python的类、对象有点类似于一个命名空间,因此在调用类、对象的方法时,一定要加上
.
,也就是类.
或者对象.
的形式。
class Dog:
def run(self):
self.jump()
print("狗在跑")
def jump(self):
print("狗在跳")
d = Dog()
d.run()
返回self
- self参数可当成实例方法的返回值
- 把self参数作为返回值,则可多次连续调用方法(只要该方法也返回self)
class Plant:
def __init__(self, height = 2):
self.height = height
def grow(self):
self.height += 10
p = Plant()
print(p.height)
p.grow()
print(p.height)
- 上面的程序是正常的,没有返回值self的,运行结果是
2
,12
。如果方法grow
返回值是self
,那么就是grow方法返回了调用者本身,那么就可以写成以下形式:
class Plant:
def __init__(self, height = 2):
self.height = height
def grow(self):
self.height += 10
return self
p = Plant()
p.grow().grow().grow().grow()
print(p.height)
- 运行结果是
42
,这是一种非常神奇的python语法现象。
使用类来调用实例方法
- 前面说过,实例方法要用对象来调用,但是其实类也是可以调用实例方法的(python是动态语言)。
class Role:
def test(self):
print("test方法")
r = Role()
Role.test(r)
- 注意:使用类调用实例方法时,python不会绑定方法的第一个参数;如果实例方法定义了一个self参数,使用类调用实例方法时,必须手动传入参数值。
类方法与静态方法
- 类方法和静态方法有点相似,他们都推荐使用类来调用(其实也可以使用对象来调用)
- 定义类方法:
- 使用
@classmethod
修饰,这个东西叫函数装饰器 - 方法的第一个参数定义为
cls
(class缩写),用类调用该方法时该参数会自动绑定
。
class Tiger:
@classmethod
def info(cls):
print("info类方法")
print(cls)
print(Tiger)
Tiger.info()
t = Tiger()
t.info()
- 定义静态方法:
- 使用
@staticmethod
修饰 - 对方法参数没有要求,无论如何都不会自动绑定。
class Tiger:
@staticmethod
def info(p):
print("info静态方法")
print(p)
Tiger.info("lancibe")
t = Tiger()
t.info(t)
- 所以把静态方法当做一个函数完全没有问题
- 关于形参会不会自动绑定的问题,有如下表格:
| 实例方法 | 类方法 | 静态方法 |
---|
对象调用 | 自动绑定 | 自动绑定 | 不自动绑定 |
类调用 | 不自动绑定 | 自动绑定 | 不自动绑定 |
总结
- 类方法和静态方法的共性:都可以使用类和对象调用
- 类方法的自动绑定与不绑定
- 静态方法总是不绑定