day18知识点

本文深入探讨了Python中的面向对象编程,包括对象方法、类方法和静态方法的定义、调用及应用场景。通过实例展示了如何使用这些方法,并解释了类和对象调用方法的顺序。此外,还讨论了继承、重写以及对象属性的增删改查操作,为读者提供了全面理解Python OOP的知识框架。
摘要由CSDN通过智能技术生成

# 一、类方法和静态方法

##1.对象方法

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

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

##2.类方法

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

##3.静态方法

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


class Demo:
    num = 61

    def func1(self):
        pass

    @classmethod
    def func2(cls):
        print(f'cls:{cls}')
        # cls指向当前类, 当前类能做的,cls都可以做
        d2 = cls()   # cls可以创建对象
        print(d2)
        print(cls.num)   # cls使用类属性
        pass

    @staticmethod
    def func3():
        pass


# 使用类属性
print(Demo.num)

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

# 调用类方法
Demo.func2()
print(f'Demo:{Demo}')


class Math:
    pi = 3.1415926

    @staticmethod
    def is_prime(num):
        print(num)

    @classmethod
    def c_area(cls, r):
        print(cls.pi*r**2)


# 练习:用面向对象实现斗地主发牌的功能
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):
        # 洗牌
        shuffle(self.pokers)
        # 把一副牌转换成迭代器
        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的基类,所有的类都直接或者间接的继承它)
class A:
    x = 100

    def __init__(self):
        self.y = 200
        self.z = 300

    def func1(self):
        print('对象方法:', self.x, self.y)

    @staticmethod
    def func2():
        print('你好!')

    @classmethod
    def func3(cls):
        print('cls:', cls)
        print("类方法")


class B(A):
    pass

## 3.在子类中添加内容

# 在子类拥有父类的属性和方法的基础上添加属于自己特有的属性和方法
1)添加类属性和方法
直接在子类中定义新的类属性和新的方法

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

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

# 先看当前类中有没有对应的方法,如果没有看父类中有没有,如果父类没有就看父类的父类,.... 以此类推,直到直到object都没有的时候才报错
class C:
    num = 100

    def __init__(self, a):
        print('C中的init')
        self.a = a
        self.b = 200

    @classmethod
    def func1(cls):
        print('C中的类方法')


class D(C):
    count = 10

    def __init__(self):
        super().__init__(100)    # 调用当前类的父类的__init__方法
        print('D中的init')
        self.c = 300

    def func2(self):
        print('D中的对象方法')

    @classmethod
    def func3(cls):
        print('D中的类方法')


print(D.num)
print(D.count)

D.func1()
D.func3()

d = D()
# d.func2()

print(d.a, d.b)
print(d.c)

#三、重写

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

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

    def func2(self):
        print('A中的func2')


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

    def func2(self):
        pass


a = A()
b = B()

b.func1()
# a.func1()

#四、运算符重载

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

# 在python中同一个运算符在面对不同类型的数据的功能可以完全不一样
# python在使用运算符的时候,其实是在通过数据去调用这个运算符对应的魔法方法
# 在python中每一个运算符都对应的一个名字固定的魔法方法,指定类型的数据是否支持某种运算符,就看这个类中有没有实现这个运算符对应的魔法方法
print(20 + 78)   # 98    相当于 ->  20.__add__(78)
print('abc' + 'mks')   # abcmks   ->  'abc'.__add__('mks')

print(2 ^ 2)    # 0
print({1, 2, 3, 4} ^ {3, 4, 5, 6})   # {1, 2, 5, 6}
from copy import copy, deepcopy
class A:

    def __add__(self, other):
        pass

    def __sub__(self, other):
        pass
    pass


a1 = A()
a2 = A()
print(a1 + a2)
print(a1 - a2)

# 30 - 20
print('=============================================')


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 __lt__(self, other):
        # return self.score < other.score
        return self.age < other.age

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


stu1 = Student('小花', 19, 90)
stu2 = Student('小明', 23, 78)
stu3 = Student('Tom', 22, 99)
print(stu1 + stu2)    # stu1.__add__(stu2)
print(stu1 + stu3)
print(stu1 * 4)     # stu1.__mul__(3)

students = [stu1, stu2, stu3]
students.sort()
print(students)

#五、对象属性的增删改

class Student:
    num = 100
    __count = 200

    def __init__(self, name, age=18, gender='男'):
        self.name = name
        self.age = age
        self.gender = gender
        self.__password = '123456'

    def func1(self):
        print(self.__password)
        print(Student.__count)
        self.__func2()

    def __func2(self):
        print('函数2')




stu1 = Student('小明')
stu2 = Student('张三')

# print(stu2.__password)
print('密码:', stu1._Student__password)
stu1.func1()

print(Student.num)
# print(Student.__count)
print('count:', Student._Student__count)

# stu1.__func2()

print(stu1.__dict__)

print('===============================================')
# 1.获取对象属性
# 1)对象.属性名
print(stu1.name)
# print(stu1.height)    # 属性不存在会报错!

# 2)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

# 3.删
# 1) del 对象.属性
del stu1.age
# print(stu1.age)   # AttributeError: 'Student' object has no attribute 'age'

# 2)delattr(对象, 属性名)
delattr(stu1, 'name')
# print(stu1.name)    # AttributeError: 'Student' object has no attribute 'name'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值