美文网首页
2018-10-19继承、重写、内存管理和认识pygame

2018-10-19继承、重写、内存管理和认识pygame

作者: MW演员 | 来源:发表于2018-10-19 18:33 被阅读0次

一、类的继承

  • Python中类支持继承,并且支持多继承
1、什么是继承

父类(超类):被继承的类
子类:去继承父类的类
就是让子类直接拥有父类的属性和方法(注意:继承后父类仍然用有自己的属性和方法)
Python中所有的类都是直接或间接的继承自object类

2、怎么继承

语法:

class 类名(父类列表):
    类的内容
3、能继承什么东西

直接拥有属性和方法
能继承:对象属性、对象方法、类字段、类方法、静态方法、都可以继承
不能继承:私有的表面上不能继承(Python中没有真正的私有)
注意:如果设置了__slots__魔法会约束当前类的对象,并且会导致当前类的对象的__dict__属性不存在
继承后__slots__的值不会约束到子类的对象,但会导致子类对象的__dict__只有在当前类中添加的属性

class Person(object):
    num = 73
    __i = 80
    __slots__ = ('name', 'age')
    def __init__(self,name = '小明',age = 16):
        self.name = name
        self.age = age
        self.__sex = 'nan'

    def eat(self):
        print('%s正在吃' % self.name)

    @staticmethod
    def fun1():
        print('这是Person静态方法')

    @classmethod
    def show_num(cls):
        print('%d人类的数量' % cls.num)

class Student(Person):
    pass

stu1 = Student()
print(stu1.name, stu1.age)
stu1.eat()
print(stu1.num)
stu1.show_num()
stu1.fun1()
print(stu1.__dict__)
stu1.id = '001'
print(stu1.__dict__)

二、重写

  • 继承后子类会用有父类的属性和方法,也可以添加属于自己的属性额方法
1、添加新的方法

直接在子类中声明新的方法,新的方法只能通过子类来使用

2、重写
  • a. 子类继承父类的方法,在子类中去重新实现这个方法的功能(完全重写)
  • b. 在子类方法中通过 super().父类方法 去保留父类对应的方法功能(部分重写)
3、类中的函数的调用过程

类.方法, 对象.方法

  • 调用过程:先看当前类中是否有这个方法,如果有就直接调用当前类中相应的方法;
  • 如果没有就去当前类的父类中找相对应的方法,如果有就调用,
  • 如果没有就在去父类的父类中找依次类推直到找到基类(object)为止,
  • 如果在object中都没有找到,程序才会异常(只会向上找不会向下找)
class Person:
    def __init__(self, name = ''):
        self.name = name

    def eat(self, food):
        print('%s吃饭%s' % (self.name, food))

    @classmethod
    def get_up(cls):
        print('洗漱')
        print('换衣服')

    @staticmethod
    def run():
        print('人在跑')

class Student(Person):
    def study(self):
        print('%s 在学校' % self.name)

    @staticmethod
    def run():
        print('学生在跑')

    @classmethod
    def get_up(cls):
        # super()获取当前类的父类
        # super()当前类的父类
        super().get_up()   # 调用父类的get_up的功能
        print('背书包')

    def eat(self, food):
        # super()当前类的父类的对象
        super().eat(food)
        print('喝水')

stu1 = Student()
per1 = Person()
stu1.study()
per1.run()
stu1.run()
Student.get_up()
Person.get_up()
per1.eat('apple')

三、添加对象属性和类字段

1、添加字段
  • 直接在子类中声明新的字段
2、对象属性

子类是通过继承父类的init方法来继承父类的对象属性
当子类中没有init方法时,通过子类的构造方法创建对象时会自动调用父类的init方法

class Car:
    num = 10

class SportCar(Car):
    # 添加字段
    wheel_count = 4
    num = 8
    # 给子类添加新的属性
    def __init__(self, color):
        # 通过super()去调用父类的init方法
        super().__init__(color)   # 在子类中创建对象时用来继承父类属性的,如果不写子类就不会继承父类的属性
        self.power = 0

print(SportCar.num, SportCar.wheel_count)
print(Car.num)

# ```

练习:

声明一个人类,姓名、年龄、IDcard,要求创建人类对象的时候必须给名字赋值姓名,年龄和IDcard可以赋也可不赋
声明一个学生类,名字,年龄,IDcard、学号,成绩,
要求创建学生的时候必须给学号赋值,可以给年龄名字赋值,不能给身份证号和成绩赋值

class Person:
    """人类"""
    def __init__(self,name,age = 0, IDcard = ''):
        self.name = name
        self.age = age
        self.IDcard = IDcard
class Student(Person):
    """学生类"""
    def __init__(self, stu_id, age = 0, name = ''):
        super().__init__(name)
        self.stu_id = stu_id
        self.score = 0

per1 = Person('小明')
per2 = Person('小明', 13)
per3 = Person('小明', 13, '123456')

stu1 = Student('001', 14, '小明')
stu2 = Student('001', 14)
stu3 = Student('001', name = '小明')
3、多态
  • 继承就会产生多态(同一种事物多种形态)

四、运算符的重载

1、什么是运算符
  • 运算符重载:通过实现类的相应的魔法方法,来让类的对象支持相应的运算符
2. gt( > )和lt( < )一般只需要实现一个就可以
  • 列表元素是类的对象
  • 使用sort对列表进行排序(实现该对象的大于运算)
import copy
class Student:
    def __init__(self, name, age, score):
        self.name = name
        self.age = age
        self.score = score
    # gt就是大于符号对应的魔法方法
    def __gt__(self, other):
        # stu1 > stu2
        # self 指的是大于符号前面的值,other指的是大于符号后面的值
        return self.age > other.age

    # lt就是小于符号对应的魔法方法
    def __lt__(self, other):
        # stu1 < stu2
        # self 指的是小于符号前面的值,other指的是小于符号后面的值
        return self.age < other.age

    # add就是加号对应的魔法方法
    def __add__(self, other):
        # stu1 + stu2
        # self 指的是加号号前面的值,other指的是加号后面的值
        return [self.score , other.score]

    # 乘就是乘号对应的魔法方法
    def __mul__(self, other):
        result = []
        if isinstance(self, Student):
            for _ in range(other):
                result.append(copy.copy(self))
            return result
        else:
            for _ in range(self):
                result.append(copy.copy(other))
            return result

        # stu1 * stu2
        # self 指的是乘号号前面的值,other指的是乘号后面的值


stu1 = Student('aa', 12, 78)
stu2 = Student('bbb', 18, 90)

print(stu1 > stu2)
print(stu1 < stu2)
print(stu1 + stu2)
a = stu1 * 5  # 能实现
# 5 * stu1 不可能实现
for stu in a:
    print(stu.__dict__)

五、内存管理机制

1、什么是内存管理
  • Python中的内存管理(自动管理):原理垃圾回收机制
  • 内存结构:栈区间和堆区间,栈区间中的内存是系统自动开辟自动释放堆区间的内存需要手动申请和释放,但是目前大多数编程语言,都提供了一套属于自己的关于堆中的内存的管理方案,python中垃圾回收机制是用来管理内存的释放
2、开辟内存空间的过程

Python中的数据都是存在堆中,数据的地址(变量)都是在栈区间
Python中将值赋给变量时会现在堆中开辟空间然后在将数据对应的地址返回给变量,存在栈中。
但是如果数据是数字和字符串,会现在缓存区中查看这个数据之前是否已经创建过,如果没有就去创建空间存储数据,然后降地址返回,
如果之前创建过就直接将之前的地址返回

3、内存的释放(垃圾回收机制)

原理:系统每隔一定时间就会去检查=测当前程序中所有的对象的引用计数值是否为0,如果引用计数是0对象对应的内存就会被销毁,如果不是0就不销毁

4、引用计数

每个对象都有引用计数属性,用来存储当前对象被引用的次数,可以通过sys模块中的getrefcount去获取对象的引用计数值

import sys
aa = [1, 2, 3, 4]
print(sys.getrefcount(aa))

5、增加引用计数:增加引用(增加保存当前对象地址的变量的个数)
6、减少引用计数
  • a. del 删除引用(变量)
  • b. 修改存储对象地址变量的值

六、pygame模块

  • pygame是一个Python用来写2D游戏的第三方库
# 第三方库的导入
import pygame

# 1、游戏初始化
pygame.init()

# 2、创建游戏界面
# 图片、文字、
screen = pygame.display.set_mode((900, 700))

# 显示图片
# pygame.image.load(图片地址): 打开一张图片,返回图片对象
image = pygame.image.load('./files/timg.jpg')

# 图片渲染到窗口
# 窗口.blit(图片对象,位置(坐标)) 坐标格式(元祖):(x坐标, y坐标)
# 程序中的坐标原点在左上角
screen.blit(image, (-700, -100))

# 将图片展示到窗口上
pygame.display.flip()


# 3、创建游戏循环
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            print('点了关闭按钮')
            exit()  # 结束程序(结束线程)

相关文章

网友评论

      本文标题:2018-10-19继承、重写、内存管理和认识pygame

      本文链接:https://www.haomeiwen.com/subject/disuzftx.html