day18-面向对象进阶

类方法和静态方法

类中方法分为:对象方法、类方法和静态方法
  1. 对象方法

    怎么定义: 直接定义在类中的函数
    怎么调用: 用对象来调用 -> 对象.对象方法()
    特点: 自带参数self;self调用的时候不用传参,指向当前对象(谁调用指向谁)
    什么时候用: 如果实现函数的功能,需要用到对象属性,就将这个函数定义成对象方法

    用对象调用对象方法,也叫给这个对象发一个消息

  2. 类方法

    怎么定义: 在类中,定义函数前加@classmethod装饰器
    怎么调用: 用类来调用 -> 类名.类方法()
    特点: 自带参数cls;cls调用的时候不用传参,指向当前类(谁调用指向谁或者谁的类)
    什么时候用: 实现函数的功能在不需要对象属性的前提下,需要类(类属性),就是用类方法

  3. 静态方法

    怎么定义: 在类中,定义函数前加@staticmethod装饰器
    怎么调用: 用类来调用 -> 类名.静态方法()
    特点: 没有默认参数,相当于定义在类中的普通函数
    什么时候用: 实现函数的功能不需要对象(对象属性)也不需要类(类属性)

class Dome:
    num = 20

    def func1(self):
        pass

    @classmethod
    def func2(cls):
        d2 = cls()  # cls可以创建对象
        print(cls.num)  # cls使用类属性
        pass

    @staticmethod
    def func3():
        pass
    
 
# 使用类属性
print(Dome.num)

# 调用对象方法
d = Dome()
d.func1()

# 调用类方法
Dome.func2()
  • 练习:用面向对象实现斗地主发牌的功能
import random


class Poker:
    nums = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
    colors = ['♣', '♥', '♠', '♦']

    def __init__(self, num, color):
        self.num = num
        self.color = color

    def __repr__(self):
        return f'{self.color}{self.num}'

    @classmethod
    def a_deck_of_cards(cls):
        pokers = [Poker(n, c) for n in cls.nums for c in cls.colors]
        pokers.extend([Poker('Joker', ' '), Poker('joker', ' ')])
        return pokers


class PokerGame:
    def __init__(self):
        # 一副牌
        self.pokers = Poker.a_deck_of_cards()
        # print(self.pokers)

    def deal_cards(self):
        random.shuffle(self.pokers)
        # return self.pokers
        """
        play_a = [x for x in self.pokers[0:51:3]]
        play_b = [x for x in self.pokers[1:51:3]]
        play_c = [x for x in self.pokers[2:51:3]]
        landlord_card = [x for x in self.pokers[51::]]
        return play_a, play_b, play_c, landlord_card
        """
        # 把一副牌转化成迭代器
        p = iter(self.pokers)
        player1 = []
        player2 = []
        player3 = []
        for _ in range(17):
            player1.append(next(p))
            player2.append(next(p))
            player3.append(next(p))
        player1.sort(key=PokerGame.key, reverse=True)
        player2.sort(key=PokerGame.key, reverse=True)
        player3.sort(key=PokerGame.key, reverse=True)
        return player1, player2, player3, list(p)

    @staticmethod
    def key(item: Poker):
        nums = {'Joker':17, 'joker':16, '2':15, 'A':14, 'K':13, 'Q':12, 'J':11}
        num = item.num
        return int(num) if '3' <= num <= '9' or num == '10' else nums[num]


game = PokerGame()
p1, p2, p3, d = game.deal_cards()
print(p1)
print(p2)
print(p3)
print('底牌:', d)

继承

  1. 什么是继承

    让子类直接拥有父类的属性和方法的过程

    子类: 继承者
    父类: 被继承者

  2. 怎么继承

    语法:
    class 类名(父类列表):
    类的内容
    说明:
    父类列表 - 父类1, 父类2, 父类3, …

    注意:
    如果定义类的时候没有些继承关系,那么这个类默认继承自 object 类(object是python的基类,所有的类都直接或者间接的继承它)

  3. 在子类中添加内容

    在子类拥有父类的属性和方法的基础上添加属于自己特有的属性和方法

    1. 添加类属性和方法
      直接在子类中定义新的类属性和新的方法

    2. 添加对象属性
      对象属性是通过继承父类的__init__方法而继承到的

  4. 类和对象调用方法的顺序:

    先看当前类中有没有对应的方法,如果没有看父类中有没有,如果父类没有就看父类的父类,…以此类推,直到找到object都没有的时候才报错

    class C:
        num = 100
    
        def __init__(self, a):
            print('C中的init方法')
            self.a = a
            self.b = 20
    
        @classmethod
        def func1(cls):
            print('C中的类方法')
    
    
    class D(C):
        count = 10
    
        def __init__(self):
            super().__init__(999)      # 调用当前类的父类的__init__方法
            print('D中的init方法')
            self.c = 888
    
        def func2(self):
            print('D中的对象方法')
    
        @classmethod
        def func3(cls):
            print('D中的类方法')
    
    
    print(D.num, D.count)
    D.func1()
    d = D()
    d.func2()
    D.func3()
    print(d.a, d.b)
    

重写

重写:在子类中重新定义父类中的方法

class A:
    def func1(self):
        print('A中的func1')


class B(A):
    def func1(self):
        super().func1()
       
        print('B中的func1')

    def func2(self):
        pass


a = A()
b = B()
b.func1()
a.func1()

运算符重载

  1. 在python中使用运算符的本质

    在python中同一个运算符在面对不同类型的数据的时候,功能可以完全不一样
    python中在使用运算符的时候,其实是在通过数据去调用这个运算符对应的魔法方法
    在python中每一个运算符都对应一个名字固定的魔法方法,指定类型的数据是否支持某种运算符,就看这个类中有没有实现这个运算符对应的魔法方法

from copy import copy

class Student:
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score

    # self指向+前面的数据,other指向+后面的数据
    # 返回值: 运算结果
    def __add__(self, other):
        return self.score + other.score

    def __mul__(self, other):
        return [copy(self) for _ in range(other)]

    def __repr__(self):
        return f'<{str(self.__dict__)[1:-1]}, _id:{id(self)}>'

    # 注意: 大于和小于对应的方法只需要写一个,另外一个直接执行
    def __lt__(self, other):
        return self.score < other.score


stu1 = Student('小花', 18, 90)
stu2 = Student('小明', 19, 80)
stu3 = Student('小红', 20, 70)

print(stu1 + stu3)  # stu1.__add__(stu2)
print(stu1 * 3)
students = [stu1, stu2, stu3]
students.sort()
print(students)

对象属性的增删改查

class Student:
    def __init__(self, name, age=18, gender='男'):
        self.name = name
        self.age = age
        self.gender = gender


stu1 = Student('小明')
stu2 = Student('张三')
  1. 获取对象属性

    对象.属性名

    print(stu1.name)
    # print(stu1.height)  -  AttributeError 属性不存在会报错!
    
    # getattr(对象, 属性名)
    print(getattr(stu1, 'name'))
    # print(getattr(stu1, 'height'))  -  报错!
    print(getattr(stu1, 'height', 180))  # 返回180
    
    x = 'age'
    print(getattr(stu1, x))
    
  2. 增改

    1. 对象.属性名 = 值

      stu1.name = '小花'
      print(stu1.name)
      # 属性存在会修改,没有会增加
      stu1.weight = 120
      print(stu1.weight)
      
    2. setattr(对象, 属性名, 值)

      setattr(stu1, 'age', 20)
      print(stu1.age)     # 20
      
      setattr(stu1, 'score', 100)
      print(stu1.score)   # 100
      
      1. del 对象.属性

        del stu1.age
        # print(stu1.age)  - AttributeError  报错!
        
      2. delattr(对象, 属性名)

        delattr(stu1, 'name')
        # print(stu1.name)  - AttributeError  报错!
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值