一、 一、面向过程:核心是过程,过程就是解决过程的步骤,即先干什么,再干什么,基于面向过程设计的程序,就好比在设计一条流水,是一种机械思维方法 优点:复杂的问题简单化 缺点:可扩展性差(牵一发而动全身) 应用场景:Linux内核,httpd,git
二、面向对象:核心是对象,要理解对象应该把自己当成上帝,在上帝眼中一切存在的事务都是对象,不存在的就创建出来。对象是特征(变量)与技能(函数)的结合体。 优点:可扩展性强 缺点:无法像面向过程一样准确的知道什么阶段发生什么事,会有什么结果 应用场景:与用户层交互多的、公司内部的软件,游戏、互联网软件 python中一切皆对象 定义一个对象就对与产生了3个属性:如定义x = 10 id:可以代表内存地址但不是内存地址 # print(id(x)) #1477693456 身份 tpye:类型或者说类 # print(type(x)) #<class 'int'> value:该变量的值。 print(x) # 10 is:身份运算符,判断id值是否一致。内存地址相同则id相同,判断为True, 如果只是值相同,则id不一定相同。 如:x = 300 y = 300 x is y 判断为False 必须在cmd执行,PyCharm会有一个自动优化 == :判断的是两个变量的值是否相等
二、在python3中统一了类与类型的概念 s = str('打豆豆') #这个s就是一个字符串类型也可以说是一个str类 #查看源码,str/int等都是定义为一个类
三、类与对象 对象是特征(变量)与技能(函数)的结合,类是一系列对象共有的特征与技能的结合体 在程序中:先定义类,再实例化出对象
定义类的语法: class 类名: '''注释''' 类体(可以是任意的代码)
#定义中国人类:
#现实中:现实存在的中国人(对象)--》中国人类(共同的特征:中国人,共同的技能:说汉语)
#定义:
class Chinese:
country = 'China'
def __init__(self,name,age):
print('=====》') #只要实例化就会触发,打印
self.name = name # p1.name = 'egon'
self.age = age # p1.age = 18
def talk(self):
print('say chinese')
#类的第一种用法:实例化
# p1 = Chinese('egon',18) # =====》 只要实例化就会触发__init__函数的运行
#将p1对象本身传递给self,egon传递给变量name,18传递给age
#类的第二种用法:属性引用
# print(Chinese.country) #访问类的数据属性
# print(Chinese.__init__) #访问类的函数属性,函数属性调用直接调用
# #Chinese.__init__(1,2,4) #在这种情况下不能直接调用__init__函数,无论传几个参数,都会报错
# print(Chinese.__dict__) #查看类的属性字典,或者说是查看类的名称空间
#{'talk': <function Chinese.talk at 0x0000000000BA80D0>, '__module__': '__main__', 'country': 'China', '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__init__': <function Chinese.__init__ at 0x0000000000BA8048>, '__dict__': <attribute '__dict__' of 'Chinese' objects>, '__doc__': None}
#访问类的数据属性或者函数属性其实就是访问该类的名称空间中的字典,通过该字典的zifuc xings de keyzhi lai fanw valuezhi
# print(Chinese.country) #等同于 #China 在这里country是类的属性,实际是在名称空间中查找该字符串格式的key
# print(Chinese.__dict__['country']) #China #在这里country是名称空间字典中的字符串形式的key
# print(p1.__dict__) #对象也有名称空间,但对象只是存储数据属性
# #{'age': 18, 'name': 'egon'} 名称空间只是包含初始化时的数据属性
# print(type(p1)) #<class '__main__.Chinese'> p1的类型是Chinesee
# p1 = Chinese('egon',18)
# p2 = Chinese('alex',10000)
# p3 = Chinese('yuanhao',9000)
# print(id(p1.country)) #11780984
# print(id(p2.country)) #11780984 访问的类中的数据属性是共用的
# print(id(Chinese.country)) #11780984
#方法是绑定到对象身上的
#绑定方法:绑定到谁身上,就是给谁用的,谁来调用就会自动把自己当做第一个参数传递进去
# print(Chinese.talk) #<function Chinese.talk at 0x00000000011A70D0>
# print(p1.talk) #<bound method Chinese.talk of <__main__.Chinese object at 0x00000000011A5438>>
# print(p2.talk) #<bound method Chinese.talk of <__main__.Chinese object at 0x00000000011A5438>>
# print(p3.talk) #<bound method Chinese.talk of <__main__.Chinese object at 0x0000000000B85550>>
# print(Chinese.talk()) #正常来说类的函数属性是不能直接被类调用的,因为1、类是需要对象去实现的,2、需要传递一个对象名
# print(Chinese.talk(p1))
定义在类内部的变量,是所有对象共有的,id全一样 定义在类内部的函数,是绑定到所有对象的,是给对象来用,obj.func()会把obj本身当做第一个参数传入 因为对象是绑定方法,所以对象是方法,类的就是函数。
因为对象会将自己作为参数传入 如: obj1 = list([1,3,4]) obj1.append(444)
#模拟下来就是 obj1.append(self,444) 对象的名称空间 类的名称空间 对对象来说,先找该对象的名称空间,如果找不到,则找该类的名称空间。再找不到,就会报错。
练习
#练习1、实现一个类,计数功能,示例化多少次就统计一次
class Count:
count = 0
def __init__(self):
Count.count += 1 #正解
#self.count += 1 #只是对象自己的count属性
print(Count.count)
print(self.count)
# print(Count.count)
# p1 = Count() #1,2
# p1 = Count()
# p2 = Count() #2,3
# p3 = Count() #3,4
#学生类
class Student:
tag = 123323
def __init__(self,ID,name,age):
self.id = ID
self.name = name
self.age = age
def walk(self):
print('%s is walking' % self.name)
# p1 = Student(1,'agen',18)
# print(p1.name)
# print(p1.tag)
# p1.walk() #agen is walking
#练习3、游戏定义两个英雄的类
#对象之间的交互
class Garen:
camp = 'Demacia' #阵营
def __init__(self,nickname,life_value=200,aggressivity=100):
self.nickname = nickname
self.life_value = life_value
self.aggressivity = aggressivity
def attack(self,enemy):
enemy.life_value -= self.aggressivity
class Riven:
camp = 'Noxus' #阵营
def __init__(self,nickname,life_value=100,aggressivity=200):
self.nickname = nickname
self.life_value = life_value
self.aggressivity = aggressivity
def attack(self,enemy):
enemy.life_value -= self.aggressivity
g1 = Garen('欧德博爱')
g2 = Riven('艾利克斯')
print(g2.life_value) #100
g1.attack(g2) #对象的交互:发送了一条消息,称为向g发送了attack指令
print(g2.life_value) #0