# 三大编程范式:
# 1、面向过程编程
# 2、函数式编程
# 3、面向对象编程
# 特点:
# 面向过程---复杂度的问题流程化,进而简单化(一个复杂的问题,分成一个个小的步骤去实现)
# 面向过程的设计就好比精心设计好一条流水线,是一种机械式的思维方式
# 面向对象---解决了程序的扩展性。对某一个对象单独修改,会立刻反映到整个体系中,如对游戏中一个人物参数的特征和技能修改都很容易。
# 对象是具体的存在,而类仅仅只是一个概念,并不真实存在!!
# 在程序中:务必保证先定义类,后产生对象!!
#
# 如果我们把数据和动作内嵌到一个结构(函数或类)中,那么我们就有了一个“对象系统”(对象就是数据与函数整合到一起的产物)
#
#
# ##### 面向对象设计:将一类具体事物的数据和动作整合到一起,即为面向对象设计。
# ##### 面向对象编程:用定义类+实例/对象的方法去实现面向设计。
#
# 类------把一类事物的相同特征和动作整合到一起就是类,类是一个抽象的概念;
# 对象------基于类而创建的一个具体的事物(一个具体的存在),也是特征和动作整合到一起;
# 实例化------由类生产对象的过程叫实例化;
# 例子:----初接触
# def people(name,age,gender): # 这是一个类,统称为:人
# def eat(x):
# print("%s正在吃饭饭,请不要打扰"%x["name"])
# def wushu(x):
# print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(x["name"],x["name"],x["gender"],x["age"]))
# def feature(name,age,gender): # 对对象进行初始化
# dic={"name":name,"age":age,"gender":gender,"eat":eat,"wushu":wushu}
# return dic
# return feature(name,age,gender)
# people01=people("newmet1",15,"男") # 生成一个人(对象),叫(newmet1),这个对象是符合“人”这一类中特征与动作的一个具体的存在
# print(people01)
# people01["wushu"](people01)
# people01["eat"](people01)
# 例子:----面向对象编程:
class people: # 这是一个类,统称为:人
def eat(self):
print("%s正在吃饭饭,请不要打扰"%self.name)
def wushu(self):
print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(self.name,self.name,self.gender,self.age))
def __init__(self,name,age,gender): # 初始化函数
self.name=name
self.age=age
self.gender=gender
people01=people("newmet1",15,"男") # 生成一个人(对象),叫(newmet1),这个对象是符合“人”这一类中特征与动作的一个具体的存在
print(people01.__dict__) # {'name': 'newmet1', 'age': 15, 'gender': '男'}
people01.eat() # newmet1正在吃饭饭,请不要打扰
people01.wushu() # newmet1正在准备开始练功:(欲练此功,必先自宫!)哎!newmet1 男 年仅15岁
# 用面向对象语言写程序(是利用class等方法写),和一个程序的设计是面向对象的,完全是两回事!!
01-面向对象设计
#-------------- 类 --------------#
# class School:
# # 这个类具体是干什么用的 #
# pass
# v=School() # 类的实例化(类名+())
# print(v) # <__main__.School object at 0x00000000020A6400>
# 一、经典类、新式类
# python2 中,类分:经典类、新式类;
# python3 中,类只有新式类(就是python2中的经典类)
# 经典类:
# class 类名:
# pass
# 新式类:
# class 类名(父类): # 这个类继承自--父类
# pass
# 二、类:属性:
# 1、数据属性
# 2、函数属性
class friend:
"这是一个朋友类"
v=111
def s():
print("222")
print(dir(friend)) # 查出的是一个名字列表
print(friend.__dict__) # 查看属性字典(内存地址)
print(friend.v) # 111
friend.s() # 222
print(friend.__dict__["v"]) # 111
friend.__dict__["s"]() # 222
print(friend.__name__) # friend
print(friend.__doc__) # 这是一个朋友类
print(friend.__base__) # <class 'object'>
print(friend.__bases__) # (<class 'object'>,)
print(friend.__module__) # __main__
print(friend.__class__) # <class 'type'>
"""
#python为类内置的特殊属性
类名.__name__ # 类的名字(字符串)
类名.__doc__ # 类的文档字符串
类名.__base__ # 类的第一个父类(在讲继承时会讲)
类名.__bases__ # 类所有父类构成的元组(在讲继承时会讲)
类名.__dict__ # 类的属性字典
类名.__module__ # 类定义所在的模块
类名.__class__ # 实例对应的类(仅新式类中)
"""
02-类
class people: # 这是一个类,统称为:人
def eat(self):
print("%s正在吃饭饭,请不要打扰"%self.name)
def wushu(self):
print("%s正在准备开始练功:(欲练此功,必先自宫!)哎!%s %s 年仅%d岁"%(self.name,self.name,self.gender,self.age))
def __init__(self,name,age,gender): # 初始化函数
self.name=name
self.age=age
self.gender=gender
v1=people("newmet1",15,"男") # 实例化的过程 self --- v1 其就是实例化的结果
print(v1.__dict__) # {'name': 'newmet1', 'age': 15, 'gender': '男'}
v1.eat() # 自动给eat传了一个self参数 # newmet1正在吃饭饭,请不要打扰
v1.wushu() # 自动给wushu传了一个self参数 # newmet1正在准备开始练功:(欲练此功,必先自宫!)哎!newmet1 男 年仅15岁
print(v1.__dict__["name"]) # newmet1
print(v1.name) # newmet1
03-对象
class friend:
def __init__(self,name):
print("名字:%s"%name)
name="newmet"
def play_ball(self):
print("正在打球")
# 增加
# friend.age=18
#
# def eat():
# print("函数属性增加")
# friend.eat=eat
# print(friend.__dict__)
# friend.eat()
# 删除
# del friend.name
# print(friend.__dict__)
# 修改
friend.name="2222"
def eat():
print("函数属性修改")
friend.play_ball=eat
print(friend.name)
print(friend.play_ball())
04-类属性增删修查
class friend:
def __init__(self,name):
self.name=name
age=18
def play_ball(self):
print("正在打球")
v=friend("newmet")
print(v.__dict__)
# 查看
# print(v.age)
# print(v.play_ball)
# 增加 (实例属性只能增加数据属性)
v.gender="男"
print(v.__dict__)
print(v.gender)
# 修改
v.name="121"
print(v.__dict__)
print(v.name)
05-实例属性增删修查
country="中国-----------"
class Chinese:
country="中国"
def __init__(self,name):
self.name=name
print(">>>",country) # 没.(没实例化) 不在类中找,与实例无关
def play_ball(self,ball):
print("%s 正在玩 %s" %(self.name,ball))
print(Chinese.__dict__)
print(Chinese.country) # 中国
p=Chinese("new") # >>> 中国----------- 没.(没实例化) 不在类中找,与实例无关
print("实例化",p.country) # 实例化 中国
06-对象与实例属性
#--------------------------------- 静态属性 --------------------------------#
# class Room:
# def __init__(self,name,owner,length,width,height):
# self.name=name
# self.owner=owner
# self.length=length
# self.width=width
# self.heigth=height
# @property # 封装逻辑。 隐藏背后的逻辑,调用方式表面上和调用数据属性一样。
# def cal_area(self):
# # print("%s住在叫%s的%s平米的房子中"%(self.owner,self.name,(self.length*self.width)))
# return self.length*self.width
#
# v1=Room("1号房间","new1",50,50,4)
# v2=Room("2号房间","new2",30,30,4)
# # v1.cal_area() # new1住在叫1号房间的2500平米的房子中
# # v2.cal_area() # new2住在叫2号房间的900平米的房子中
# # v1.cal_area # new1住在叫1号房间的2500平米的房子中(类中增加 @property 后,不需要加括号)
# # v2.cal_area # new2住在叫2号房间的900平米的房子中 (类中增加 @property 后,不需要加括号)
#
# print(v1.cal_area) # 2500 @property隐藏背后的逻辑,调用方式表面上和调用数据属性一样。
# print(v2.cal_area) # 900
# print(v1.name) # 1号房间 调用数据属性
# print(v2.name) # 2号房间
#--------------------------------- 类方法 --------------------------------#
# class Room:
# food=1
# def __init__(self,name,owner,length,width,height):
# self.name=name
# self.owner=owner
# self.length=length
# self.width=width
# self.heigth=height
# @classmethod # 将下列方法变成可以被类调用的方法
# def cal_area(cls):
# print(cls) # <class '__main__.Room'>
# print("%s newmet"%cls.food) # 1 newmet
#
# # v1=Room("1号房间","new1",50,50,4)
# # v2=Room("2号房间","new2",30,30,4)
# Room.cal_area()
# # 类调用自己的属性方法的时候 ,与实例没有关系
#--------------------------------- 静态方法 --------------------------------#
class Room:
food=1
def __init__(self,name,owner,length,width,height):
self.name=name
self.owner=owner
self.length=length
self.width=width
self.heigth=height
@property # 封装逻辑。 隐藏背后的逻辑,调用方式表面上和调用数据属性一样。
def cal_area(self):
# print("%s住在叫%s的%s平米的房子中"%(self.owner,self.name,(self.length*self.width)))
return self.length*self.width
@classmethod # 将下列方法变成可以被类调用的方法
def cal_area1(cls):
print(cls) # <class '__main__.Room'>
print("%s newmet"%cls.food) # 1 newmet
@staticmethod
def bath(x):
print("%s 正在沐浴" %x)
Room.cal_area1()
Room.bath("new")
v1=Room("1号房间","new1",50,50,4)
v1.bath("met")
# @property ---- 和实例绑定,与类无关
# @classmethod ---- 和类绑定,与实例无关
# @staticmethod ---- 和类和实例均不绑定(类的工具包)
# @staticmethod -- 静态方法只是名义上的归属类管理,不能使用类变量和实例变量,只是类的工具包
#--------------------------------- 总结 --------------------------------#
# @property ---- 能访问类的数据、函数属性以及实例的属性
# @classmethod ---- 只能访问类的属性
# @staticmethod ---- 不能访问类、实例属性
07-静态属性_方法
#--------------------- 定义锐雯类:---------------------
class Raven:
camp='Noxus'
def __init__(self,nickname,
aggressivity=54,
life_value=414,
money=1001,
armor=3):
self.nickname=nickname
self.aggressivity=aggressivity
self.life_value=life_value
self.money=money
self.armor=armor
def attack(self,enemy):
damage_value=self.aggressivity-enemy.armor
enemy.life_value-=damage_value
#--------------------- 定义盖伦类:---------------------
class Galen:
camp='Demacia'
def __init__(self,nickname,
aggressivity=58,
life_value=455,
money=100,
armor=10):
self.nickname=nickname
self.aggressivity=aggressivity
self.life_value=life_value
self.money=money
self.armor=armor
def attack(self,enemy):
damage_value=self.aggressivity-enemy.armor
enemy.life_value-=damage_value
#--------------------- 定义装备:---------------------
class BlackCleaver:
def __init__(self,price=475,aggrev=9,life_value=100):
self.price=price
self.aggrev=aggrev
self.life_value=life_value
def update(self,obj):
obj.money-=self.price #减钱
obj.aggressivity+=self.aggrev #加攻击
obj.life_value+=self.life_value #加生命值
def fire(self,obj): #这是该装备的主动技能,喷火,烧死对方
obj.life_value-=1000 #假设火烧的攻击力是1000
#--------------------- 测试交互:---------------------
r1=Raven('草丛伦')
g1=Galen('盖伦')
b1=BlackCleaver()
print(r1.aggressivity,r1.life_value,r1.money) #r1的攻击力,生命值,护甲
if r1.money > b1.price:
r1.b1=b1
b1.update(r1)
print(r1.aggressivity,r1.life_value,r1.money) #r1的攻击力,生命值,护甲
print(g1.life_value)
r1.attack(g1) #普通攻击
print(g1.life_value)
r1.b1.fire(g1) #用装备攻击
print(g1.life_value) #g1的生命值小于0就死了
08-基于面向对象设计的一个对战游戏
# 获取指定位置上的·某个方向·指定数量的元素。
# 变化特征 "20" 右侧 0 1 (索引列r、行c、累加)
# 变化特征 "31" 上方 -1 0 (索引列r、行c、累加)
# 变化特征 "24" 左侧 0 -1 (索引列r、行c、累加)
# 变化特征 "03" 下方 1 0 (索引列r、行c、累加)
#
# def get_elements(list_target,r_index,c_index,r_dir,c_dir,count):
# """
# 获取指定位置上的·某个方向·指定数量的元素。
# :param list_target: list
# :param r_index:列索引
# :param c_index:行索引
# :param r_dir:方向
# :param c_dir:方向
# :param count:次数--数量
# :return:
# """
# result = []
# for item in range(count):
# r_index += r_dir
# c_index += c_dir
# result.append(list_target[r_index][c_index])
# return result
#
#
# list01=[
# ["00","01","02","03","04"],
# ["10","11","12","13","14"],
# ["20","21","22","23","24"],
# ["30","31","32","33","34"],
# ["40","41","42","43","44"]
# ]
#
#
# print(get_elements(list01,2,4,0,-1,3))
"""
该方式是:面向过程
缺点:
1.代码可读性差
2.每次调用方法,都需要思考方向(索引变化)的特征
"""
# 解决方法:
# 1.使用一个类,包装两个数据(行/列)
# 2.利用静态方法
class Vector2:
def __init__(self, x, y):
self.x = x
self.y = y
# def right(self):
# return Vector2(0,1)
# 静态方法:不依赖于对象、类
@staticmethod
def right():
return Vector2(0, 1)
@staticmethod
def up():
return Vector2(-1, 0)
@staticmethod
def down():
return Vector2(1, 0)
@staticmethod
def left():
return Vector2(0, -1)
def get_elements(list_target, vect_pos, vect_dir, count):
"""
获取指定位置上的·某个方向·指定数量的元素。
:param list_target: list
:param r_index:列索引
:param c_index:行索引
:param r_dir:方向
:param c_dir:方向
:param count:次数--数量
:return:
"""
result = []
for item in range(count):
vect_pos.x += vect_dir.x
vect_pos.y += vect_dir.y
result.append(list_target[vect_pos.x][vect_pos.y])
return result
list01 = [
["00", "01", "02", "03", "04"],
["10", "11", "12", "13", "14"],
["20", "21", "22", "23", "24"],
["30", "31", "32", "33", "34"],
["40", "41", "42", "43", "44"]
]
print(get_elements(list01, Vector2(2, 0), Vector2.right(), 3))
09-静态方法_精华案例