【Python 基础】Python全栈体系(五)

Python 基础

第六章 2048 核心算法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

"""
    2028 核心算法
        降维
"""
list_merge = [2, 0, 0, 2]


# 1. 定义函数,将list_merge中的零元素移动到末尾
# [2,0,0,2]  -->  [2,2,0,0]
# [4,0,4,0]  -->  [4,4,0,0]
def zero_to_end():
    """
        零元素移动到末尾
        思路:从后向前依次判断,如果是零元素,则删除后追加零。
    """
    for i in range(len(list_merge) - 1, -1, -1):
        if list_merge[i] == 0:
            del list_merge[i]
            list_merge.append(0)


# 测试
# zero_to_end()
# print(list_merge)

# 2. 定义函数,将list_merge中的元素进行合并(相邻且相同)
# [2,0,0,2]  -->  [0,0,2,2] --> [0,0,0,4]
# [4,0,4,0]  -->  [4,4,0,0] --> [8,0,0,0]

# [2,2,2,2]  --> [4,4,0,0]
def merge():
    """
        合并
        思路:
            将零元素后移
            判断如果相邻且相同则合并
    """
    zero_to_end()
    for i in range(len(list_merge) - 1):
        for j in range(i+1,len(list_merge)):
            if list_merge[i] == list_merge[j]:
                list_merge[i] += list_merge[j]
                del list_merge[j]
                list_merge.append(0)

            # if list_merge[i] == list_merge[i + 1]:
            # list_merge[i] += list_merge[i + 1]
            # del list_merge[i + 1]
            # list_merge.append(0)


# merge()
# print(list_merge)

map = [
    [2, 4, 4, 2],
    [2, 4, 4, 2],
    [0, 4, 2, 0],
    [2, 0, 2, 0],
]





# 3. 定义函数,将二维列表map中的元素向左移动
def move_left():
    """
        向左移动
        思路:将每行(一维列表)赋值给全局变量list_merge
              在通过merge函数操作数据
    """
    global list_merge
    for line in map:
        list_merge = line
        merge()


# move_left()
# print(map)


# 4.定义函数,将二维列表map中的元素向右移动
def move_right():
    """
        向右移动
        思路:将每行(反向切片)赋值给全局变量list_merge
              在通过merge函数操作数据
              再对list_merge(反向切片)
    """
    global list_merge
    for line in map:
        # 因为切片,所以创建了新列表
        list_merge = line[::-1]
        merge()  # 操作的是新列表
        line[::-1] = list_merge
        # line = list_merge[::-1]

# move_right()
# print(map)


def square_matrix_tranpose(matrix):
    for c in range(len(matrix) - 1):
        for r in range(c + 1, len(matrix)):
            matrix[r][c], matrix[c][r] = matrix[c][r], matrix[r][c]


# 5. 定义函数,将二维列表map中的元素向上移动
def move_up():
    """
        思想:方阵转置
             调用向左移动
             方阵转置
    """
    square_matrix_tranpose(map)
    move_left()
    square_matrix_tranpose(map)

# 6. 定义函数,将二维列表map中的元素向下移动
def move_down():
    """
        思想:方阵转置
             调用向右移动
             方阵转置
    """
    square_matrix_tranpose(map)
    move_right()
    square_matrix_tranpose(map)

move_down()
for i in map:
    print(i)

第七章 面向对象

一、概述

1. 面向过程
  1. 分析出解决问题的步骤,然后逐步实现。
    例如:婚礼筹办
    – 发请柬(选照片、措词、制作)
    – 宴席(场地、找厨师、准备桌椅餐具、计划菜品、购买食材)
    – 婚礼仪式(定婚礼仪式流程、请主持人)
  2. 公式:程序 = 算法 + 数据结构
  3. 优点:所有环节、细节自己掌控。
  4. 缺点:考虑所有细节,工作量大。
2. 面向对象
  1. 找出解决问题的人,然后分配职责。
    例如:婚礼筹办
    – 发请柬:找摄影公司(拍照片、制作请柬)
    – 宴席:找酒店(告诉对方标准、数量、挑选菜品)
    – 婚礼仪式:找婚庆公司(对方提供司仪、制定流程、提供设备、帮助执行)
  2. 公式:程序 = 对象 + 交互
  3. 优点
    (1) 思想层面:
    – 可模拟现实情景,更接近于人类思维。
    – 有利于梳理归纳、分析解决问题。
    (2) 技术层面:
    – 高复用:对重复的代码进行封装,提高开发效率。
    – 高扩展:增加新的功能,不修改以前的代码。
    – 高维护:代码可读性好,逻辑清晰,结构规整。
  4. 缺点:学习曲线陡峭。
3. 小结
  • 面向过程:关心解决问题的步骤
  • 面向对象:关心谁在干嘛

二、类和对象

1. 基础概念
  1. 抽象:从具体事物中抽离出共性、本质,舍弃个别、非本质过程。
  2. 类:一个抽象的概念,即生活中的”类别”。
  3. 对象:类的具体实例,即归属于某个类别的”个体”。
  4. 类是创建对象的”模板”。
    – 数据成员:名词类型的状态。
    – 方法成员:动词类型的行为。
2. 语法
2.1 定义类
  1. 代码
class 类名:
	“””文档说明”””
	def _init_(self,参数列表):
		self.实例变量 = 参数
	方法成员
  1. 说明
    – 类名所有单词首字母大写.
    – _init_ 也叫构造函数,创建对象时被调用,也可以省略。
    – self 变量绑定的是被创建的对象,名称可以随意。
2.2 创建对象(实例化)
  • 变量 = 构造函数 (参数列表)
"""
    面向对象编程

    手机
        数据:品牌、价格、颜色..
        行为:通话../
"""


class Cellphone:
    def __init__(self, brand, price, color):
        self.brand = brand
        self.price = price
        self.color = color

    def call(self):
        print(self.brand, "打电话")


# 创建手机对象
# 会调用__init__构造函数
iphone01 = Cellphone("苹果", 9999, "绿色")
huawei01 = Cellphone("华为", 6666, "白色")
iphone01.call()
huawei01.call()

在这里插入图片描述

"""
    创建狗类
    数据成员包含但不限定于:品种、爱称、年龄、性别。
    方法成员包含但不限定于:吃。
    创建两个对象并调用方法。
"""


class Dog:
    """
        狗
    """

    def __init__(self, breed="", name="", age=0, sex=""):
        self.breed = breed
        self.name = name
        self.age = age
        self.sex = sex

    def eat(self):
        print(self.name, "在吃")


d01 = Dog("拉布拉多", "米咻", 4, "母")
d02 = Dog("拉布拉多", "黑米", 3, "公")
d01.eat()
d02.eat()

# 练习1:根据下列代码画出内存图
d03 = d01
d01.age = 5
print(d03.age)#?

d04 = d02
d02 = Dog("哈士奇","二哈",2,"公")
print(d04.name)#?

# 练习2:根据下列代码画出内存图
def fun01(p01):
    p01.name = "哈哈哈"

# fun01(d02)
# print(d02.name)# ???


list01 = [
    d01,
    d02,
    Dog("沙皮","皮皮",3,"公"),
    Dog("金毛","毛毛",1,"母"),
]

# 练习3:定义函数,在狗列表中查找所有拉拉布拉多。
def find01():
    list_result = []
    for item in list01:
        if item.breed == "拉布拉多":
            list_result.append(item)
    return list_result

# -----------------------
# re = find01()
# print("----")
# for item in re:
#     print(item.name)

在这里插入图片描述
在这里插入图片描述

3. 实例成员
3.1 实例变量
  1. 语法
    (1) 定义:对象.变量名
    (2) 调用:对象.变量名

  2. 说明
    (1) 首次通过对象赋值为创建,再次赋值为修改.
    w01 = Wife()
    w01.name = “建宁”
    w01.name = “建宁公主”
    (2) 通常在构造函数(init)中创建。
    w01 = Wife(“建宁公主,24)
    print(w01.name)
    (3) 每个对象存储一份,通过对象地址访问。

  3. 作用:描述某个对象自己的数据。

  4. _dict_:对象的属性,用于存储自身实例变量的字典。

3.2 实例方法
  1. 语法
(1) 定义:  def 方法名称(self, 参数列表):
	    		方法体
(2) 调用: 对象地址.实例方法名(参数列表)
		  	不建议通过类名访问实例方法
  1. 说明
    (1) 至少有一个形参,第一个参数绑定调用这个方法的对象,一般命名为"self"。
    (2) 无论创建多少对象,方法只有一份,并且被所有对象共享。
  2. 作用:表示对象行为。
"""
    创建老婆类,老婆列表。
    定义下列函数:
        1)获取所有老婆姓名
        2)获取颜值大于80的所有老婆对象
        3)获取年龄最大的老婆对象
        4)根据颜值对老婆列表进行升序排列
"""


class Wife:
    def __init__(self, name="", face_score=0, age=0):
        self.name = name
        self.face_score = face_score
        self.age = age

    def print_self(self):
        print(self.name, self.face_score, self.age)


list_wife = [
    Wife("阿珂", 100, 23),
    Wife("苏荃", 92, 32),
    Wife("双儿", 90, 25),
    Wife("小郡主", 76, 22),
    Wife("方怡", 75, 27),
    Wife("建宁", 86, 25),
    Wife("曾柔", 67, 24),
]


# 1)获取所有老婆姓名
def find01():
    result = []
    for item in list_wife:
        result.append(item.name)
    return result


print(find01())


# 2)获取颜值大于80的所有老婆对象
def find02():
    result = []
    for item in list_wife:
        if item.face_score > 80:
            result.append(item)
    return result


for item in find02():
    item.print_self()


# 3)获取年龄最大的老婆对象
def get_max():
    max_value = list_wife[0]
    for i in range(1, len(list_wife)):
        if max_value.age < list_wife[i].age:
            max_value = list_wife[i]
    return max_value


re = get_max()
re.print_self()


# 4)根据颜值对老婆列表进行升序排列
def order_by():
    for r in range(len(list_wife) - 1):
        for c in range(r + 1, len(list_wife)):
            if list_wife[r].face_score > list_wife[c].face_score:
                list_wife[r], list_wife[c] = list_wife[c], list_wife[r]

order_by()
print("-----------------")
for item in list_wife:
    item.print_self()
4. 类成员
4.1 类变量
  1. 语法
    (1) 定义:在类中,方法外定义变量。

    class 类名:
    	变量名 = 表达式
    

    (2) 调用:类名.变量名
    不建议通过对象访问类变量

  2. 说明
    (1) 存储在类中。
    (2) 只有一份,被所有对象共享。

  3. 作用:描述所有对象的共有数据。

4.2 类方法
  1. 语法
    (1) 定义:

    @classmethod
    def 方法名称(cls,参数列表):
         方法体
    

    (2) 调用:类名.方法名(参数列表)
    不建议通过对象访问类方法

  2. 说明
    (1) 至少有一个形参,第一个形参用于绑定类,一般命名为’cls’
    (2) 使用@classmethod修饰的目的是调用类方法时可以隐式传递类。
    (3) 类方法中不能访问实例成员,实例方法中可以访问类成员。

  3. 作用:操作类变量。

"""
    类成员
        类变量:
"""
class ICBC:
    """
        工商银行
    """
    # 类变量:大家的数据(总行的钱)
    total_money = 1000000

    @classmethod
    def print_total_money(cls):
        # print("总行的钱:",ICBC.total_money)
        print("总行的钱:",cls.total_money)

    def __init__(self, name="", money=0):
        self.name = name
        self.money = money
        # 总行的钱减少
        ICBC.total_money -= money


i01  = ICBC("陶然亭支行",100000)
ICBC.print_total_money()

i02  = ICBC("天坛支行",100000)
ICBC.print_total_money()

在这里插入图片描述

"""
    练习:对象计数器
        使用类变量记录
        使用类方法打印
"""

class Wife:
    count = 0

    @classmethod
    def print_count(cls):
        print("总共娶了",cls.count,"个")

    def __init__(self):
        Wife.count += 1

w01 = Wife()
w02 = Wife()
w03 = Wife()
w04 = Wife()
w05 = Wife()
Wife.print_count()
5. 静态方法
  1. 语法
    (1) 定义:
    @staticmethod
    def 方法名称(参数列表):
        方法体
    
    (2) 调用:类名.方法名(参数列表)
    不建议通过对象访问静态方法
  2. 说明
    (1) 使用@ staticmethod修饰的目的是该方法不需要隐式传参数。
    (2) 静态方法不能访问实例成员和类成员
  3. 作用:定义常用的工具函数。
"""
    静态方法
"""

class Vector2:
    """
        向量
    """
    def __init__(self,x = 0,y = 0):
        self.x = x
        self.y = y

    @staticmethod
    def get_left():
        return Vector2(0,-1)

    @staticmethod
    def get_right():
        return Vector2(0,1)

    @staticmethod
    def get_up():
        return Vector2(-1,0)

class DoubleListHelper:

    """
        二维列表助手类
    """
    @staticmethod
    def get_elements(list_target, vect_pos, vect_dir, count):
        list_result = []
        for __ in range(count):
            vect_pos.x += vect_dir.x
            vect_pos.y += vect_dir.y
            element = list_target[vect_pos.x][vect_pos.y]
            list_result.append(element)
        return list_result

pos = Vector2(2,1)
right = Vector2.get_right()
pos.x += right.x
pos.y += right.y

print(pos.x)
print(pos.y)

list01 = [
    ["00","01","02","03","04"],
    ["10","11","12","13","14"],
    ["20","21","22","23","24"],
    ["30","31","32","33","34"],
]

print(DoubleListHelper.get_elements(list01,Vector2(3,0),Vector2.get_right(),3))

# 练习:32位置 向上获取3个元素
print(DoubleListHelper.get_elements(list01,Vector2(3,2),Vector2.get_up(),3))
# 练习:34位置 向左获取3个元素
print(DoubleListHelper.get_elements(list01,Vector2(3,4),Vector2.get_left(),3))

三、三大特征

1. 封装
1.1 数据角度讲
  1. 定义:
    将一些基本数据类型复合成一个自定义类型。
  2. 优势:
    将数据与对数据的操作相关联。
    代码可读性更高(类是对象的模板)。
1.2 行为角度讲
  1. 定义:
    类外提供必要的功能,隐藏实现的细节。
  2. 优势:
    简化编程,使用者不必了解具体的实现细节,只需要调用对外提供的功能。
  3. 私有成员:
    (1) 作用:无需向类外提供的成员,可以通过私有化进行屏蔽。
    (2) 做法:命名使用双下划线开头。
    (3) 本质:障眼法,实际也可以访问。
    私有成员的名称被修改为:_类名__成员名,可以通过_dict_属性或dir函数查看。
  4. 属性@property:
    公开的实例变量,缺少逻辑验证。私有的实例变量与两个公开的方法相结合,又使调用者的操作略显复杂。而属性可以将两个方法的使用方式像操作变量一样方便。
    (1) 定义:
    @property
    def 属性名(self):
    	return self.__属性名
    @属性名.setter
    def 属性名(self, value):
    	self.__属性名 = value
    
    (2) 调用:
    对象.属性名 = 数据
    变量 = 对象.属性名
    (3) 说明:
    通常两个公开的属性,保护一个私有的变量。
    @property 负责读取,@属性名.setter 负责写入
    只写:属性名= property(None, 写入方法名)
"""
    封装 -- 私有成员
        障眼法:修改了私有变量名称
            本质: __变量名  -->   _类名__变量名
"""
# 1. 私有化实例变量
# 2. 提供两个公开的读写方法

class Wife:
    def __init__(self, name="", age=0):
        self.name = name
        # self.__age = age
        self.set_age(age)
    def get_age(self):
        return self.__age
    def set_age(self, value):
        if 20 <= value <= 50:
            self.__age = value
        else:
            raise Exception("我不要")
w01 = Wife("宁宁", 25)
w02 = Wife("铁锤", 26)
# print(w01.age)
w01.set_age(27)
print(w01.get_age())
# w01.sex = '男'
w01.__age = 28
# print(w01.__age)# 私有化
print(w01.__dict__)
print(w01._Wife__age)# ????
"""
    封装 -- 属性
"""
# 1. 创建实例变量
# 2. 提供两个公开的读写方法
# 3. 创建类变量存储property对象

class Wife:
    def __init__(self, name="", age=0):
        self.name = name
        self.set_age(age)
        # self.age = age

    def get_age(self):
        return self.__age

    def set_age(self, value):
        if 20 <= value <= 50:
            self.__age = value
        else:
            raise Exception("我不要")

    # 类变量
    # property 作用:拦截
    # age = property(get_age, set_age)


w01 = Wife("宁宁", 25)
w02 = Wife("铁锤", 26)
# w01.set_age(27)
w01.age = 27
print(w01.age)
print(w01.__dict__)
"""
    封装 -- 标准属性
        作用:保护实例变量
"""


# 1. 创建实例变量
# 2. 提供两个公开的读写方法
# 3. 使用@property修饰读取方法
#    使用@属性名.setter修改写入方法

class Wife:
    def __init__(self, name="", age=0):
        self.name = name
        self.age = age

    @property# 创建property对象,自动绑定下面方法(读取)
    def age(self):
        return self.__age

    @age.setter# 自动绑定下面方法(写入)
    def age(self, value):
        if 20 <= value <= 50:
            self.__age = value
        else:
            raise Exception("我不要")


w01 = Wife("宁宁", 25)
w01.age = 27
print(w01.age)
print(w01.__dict__)
"""
    创建敌人类,数据:姓名,血量(0--100),攻击力(1--50)
"""


class Enemy:
    def __init__(self, name="", hp=0, atk=0):
        self.name = name
        self.hp = hp
        self.atk = atk

    @property
    def hp(self):
        return self.__hp

    @hp.setter
    def hp(self, value):
        if 1 <= value <= 100:
            self.__hp = value
        else:
            raise Exception("血量超过范围")

    @property
    def atk(self):
        return self.__atk

    @atk.setter
    def atk(self, value):
        if 1 <= value <=50:
            self.__atk = value
        else:
            raise Exception("血量超过范围")

e01 = Enemy("灭霸", 99, 50)
print(e01.hp)
print(e01.atk)
"""
    属性 - 常见写法
"""


# 1. 读写属性
class Wife01:
    def __init__(self, age=0):
        self.age = age

    @property
    def age(self):  # 秘书
        return self.__age  # 老板

    @age.setter
    def age(self, v):
        self.__age = v

#
w01 = Wife01(25)
print(w01.age)


# 2. 只读属性
class Wife02:
    def __init__(self):
        self.__age = 26

    @property
    def age(self):  # 秘书
        return self.__age  # 老板


w01 = Wife02()
print(w01.age)


# w01.age = 100# 不能写入

# 3. 只写属性
class Wife01:
    def __init__(self, age=0):
        self.age = age

    # @age.setter
    def __set_age(self, v):
        self.__age = v

    age = property(None, __set_age)


w01 = Wife01(25)
w01.age = 26
# print(w01.age)
print(w01.__dict__)
# print(w01.__set_age)
"""
    复习
"""
class MyClass:

    # 类成员:类
    total_count = 0

    @classmethod
    def print_total_count(cls):
        print(cls.total_count)

    # 实例成员:对象
    def __init__(self, name=""):
        self.name = name

    def print_self(self):
        print(self.name)

    # 静态方法:类
    @staticmethod
    def tools():
        print("独立的功能")

c01 = MyClass()
c01.name = "xx"
c01.print_self()
1.3 设计角度讲
  1. 定义:
    (1) 分而治之
    将一个大的需求分解为许多类,每个类处理一个独立的功能。
    (2) 变则疏之
    变化的地方独立封装,避免影响其他类。
    (3) 高 内 聚
    类中各个方法都在完成一项任务(单一职责的类)。
    (4) 低 耦 合
    类与类的关联性与依赖度要低(每个类独立),让一个类的改变,尽少影响其他类。
  2. 优势:
    便于分工,便于复用,可扩展性强。
    在这里插入图片描述
"""
    封装-设计思想
        请以面向对象的思想,描述以下场景:
            老张开车去东北
"""

# 写法1:每次都会创建一辆新车
"""
class Person:
    def __init__(self, name=""):
        self.name = name

    def go_to(self, pos):
        print("去", pos)
        car = Car()
        car.run()


class Car:
    def run(self):
        print("嘟嘟嘟...")


lz = Person("老张")
lz.go_to("东北")
"""

# 写法2:老张的车
"""
class Person:
    def __init__(self, name=""):
        self.name = name
        self.car = Car()

    def go_to(self, pos):
        print("去", pos)
        self.car.run()


class Car:
    def run(self):
        print("嘟嘟嘟...")


lz = Person("老张")
lz.go_to("东北")
lz.go_to("西北")
"""


# 写法3:人与车的关系松散
class Person:
    def __init__(self, name=""):
        self.name = name

    def go_to(self, pos, vehicle):
        print("去", pos)
        vehicle.run()


class Car:
    def run(self):
        print("嘟嘟嘟...")

lz = Person("老张")
c01 = Car()
lz.go_to("东北", c01)
"""
    请以面向对象的思想,描述以下场景:
        玩家(攻击力)攻击敌人,敌人(血量)受伤后还可能死亡。
"""


class Player:
    def __init__(self, atk=0):
        self.atk = atk

    def attack(self, target):
        print("打你")
        target.damage(self.atk)


class Enemy:
    def __init__(self, hp=0):
        self.hp = hp

    def damage(self, value):
        print("呃!")
        self.hp -= value
        if self.hp <= 0:
            self.death()

    def death(self):
        print("死亡喽")


p01 = Player(50)
e01 = Enemy(100)
p01.attack(e01)
p01.attack(e01)
"""
    请以面向对象的思想,描述以下场景:
        张无忌教赵敏九阳神功
        赵敏教张无忌化妆
        张无忌上班挣了10000元
        赵敏上班挣了8000元
"""
class Person:
    def __init__(self, money,name=""):
        self.name = name
        self.money = money

    def teach(self,other,skill):
        print(self.name,"教",other.name,skill)

    def work(self):
        print(self.name,"工作挣了",self.money,"元")


zwj = Person("张无忌",10000)
zm = Person("赵敏",8000)
zwj.teach(zm,"九阳神功")
zm.teach(zwj,"化妆")
zwj.work()
zm.work()
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

柠檬小帽

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

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

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

打赏作者

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

抵扣说明:

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

余额充值