Python学习笔记——面向对象(2)

Python学习笔记

面向对象(2)

实例方法与自动绑定

  • 使用对象调用实例方法时,python会自动绑定方法的第一个参数(通常建议将该参数命名为self)
  • 根据第一个参数出现位置的不同,第一个参数所绑定的对象略有区别。但是总之,方法中的self总是代表该方法的调用者。实例方法的第一个self不需要传入,由系统自动绑定,总是绑定到方法调用者。
    • 在构造方法中引用该构造方法正在初始化的对象。
    • 在普通实例方法中引用调用该方法的对象
class User:
    def __init__(self, name = "tiger"):
        # self代表该构造器正在构造的对象
        self.name = name
    
    def info(self):
        print(self)
        print(self.name)
    
        
# User构造的对象,赋值给了u,因此User构造器中的self实际上就代表u
u = User()
print(u.name)


# User够早的对象,赋值给了u2,在User构造器中的self实际上就代表u2
u2 = User("scott")
print(u2.name)

print(u2)


# 程序用u2调用了info方法,那么info方法中的self就代表了u2
u2.info()

# 程序用u1调用了info方法,那么info方法中的self就代表了u1
u1 = User()
u1.info()
  • 注意:当python的一个方法调用另一个方法时,不可以省略self;python的类、对象有点类似于一个命名空间,因此在调用类、对象的方法时,一定要加上.,也就是类.或者对象.的形式。
class Dog:
    def run(self):
        # 一个方法调用其他方法,也需要使用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):
        # 每grow一次,height增加10
        self.height += 10
        
p = Plant()
print(p.height)
p.grow()
print(p.height)
  • 上面的程序是正常的,没有返回值self的,运行结果是212。如果方法grow返回值是self,那么就是grow方法返回了调用者本身,那么就可以写成以下形式:
class Plant:
    def __init__(self, height = 2):
        self.height = height
        
    def grow(self):
        # 每grow一次,height增加10
        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方法")


# 这样的调用是错的,因为test方法本身是实例方法,应该是使用对象来调用
# python允许使用类来调用实例方法,此时变成了“未绑定的方法”
# 因此必须显式为self传入参数值
# Role.test()
        
# 这是正确的调用方法
r = Role()
Role.test(r)
  • 注意:使用类调用实例方法时,python不会绑定方法的第一个参数;如果实例方法定义了一个self参数,使用类调用实例方法时,必须手动传入参数值。

类方法与静态方法

  • 类方法和静态方法有点相似,他们都推荐使用类来调用(其实也可以使用对象来调用)
  • 定义类方法:
    • 使用@classmethod修饰,这个东西叫函数装饰器
    • 方法的第一个参数定义为cls(class缩写),用类调用该方法时该参数会自动绑定
class Tiger:
    # 类方法两个注意点,第一个参数是cls,前面必须要@classmethod修饰
    @classmethod
    def info(cls):
        print("info类方法")
        print(cls)


print(Tiger)

# 类方法属于类本身,所以使用类来调用
# 类方法的第一个参数也会自动绑定,绑定到调用该方法的类
Tiger.info()



t = Tiger()
# 对象调用类方法也是可以的,但是注意第一个参数绑定的还是类
# 对象调用实际上也相当于用类调用类方法,第一个参数绑定当前类
t.info()



  • 定义静态方法:
    • 使用@staticmethod修饰
    • 对方法参数没有要求,无论如何都不会自动绑定。
class Tiger:
    # 静态方法两个注意点,无需定义任何形参,,前面必须要@staticmethod修饰
    # 即使这里写了若干个形参,也不会自动绑定。
    @staticmethod
    def info(p):
        print("info静态方法")
        print(p)


# 静态方法就相当于是一个函数,因此不会自动绑定
# 用类调用静态方法
Tiger.info("lancibe")


t = Tiger()
# 对象调用静态方法,也不会自动绑定,也要传入参数值
t.info(t)
  • 所以把静态方法当做一个函数完全没有问题
  • 关于形参会不会自动绑定的问题,有如下表格:
实例方法类方法静态方法
对象调用自动绑定自动绑定不自动绑定
类调用不自动绑定自动绑定不自动绑定

总结

  • 类方法和静态方法的共性:都可以使用类和对象调用
  • 类方法的自动绑定与不绑定
  • 静态方法总是不绑定
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lanciberrr

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值