python--面向对象
引言:
在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是‘类’,对象是则是这一类事物中具体的一个。
python中一切皆为对象,类型的本质就是类,所以,不管你信不信,你已经使用了很长时间的类了
>>> dict #类型dict就是类dict <class 'dict'> >>> d=dict(name='eva') #实例化 >>> d.pop('name') #向d发一条消息,执行d的方法pop 'eva'
一、面向对象编程
类的概念:具有相同属性和技能的一类事物
eg:人类
对象:就是对一个类的具体的描述
eg:具体的一个人
使用面向对象的好处:
1.使得代码之间的角色关系更加明确
2.增强了代码的可扩展性
3.规范了对象的属性的技能
面向对象的特点:结局的不确定性
面向对象编程代码思想分析:
def Person(name,sex,hp,ad): #人的模子 self = {"names":name,"sexs":sex,"hps":hp,"ads":ad} def attack(dog): #闭包 #人攻击狗 print("%s打了%s" % (self["name"],dog["name"])) #程序第 4 步 #狗掉血,狗的血-人的攻击力 dog["hp"] -= self["ad"] self["attack"] = attack #给self这个字典,添加k-v return self def Dog(name,king,hp,ad): #狗模子 self = {'name': name, 'kind':kind, 'hp': hp, 'ad': ad} def bite(person): print("%s咬了%s") (self["name"],person["name"])) #人掉血 人的血量-狗的攻击力 person["hp"] -= self["ad"] if person["hp"] <= 0:print("game over,%s win" % self["name"]) self["bite"] = bite #给self这个字典,添加k-v return self alex = Person("sb","男",10,5) #程序第 1 步 #给Person这个函数传参数,赋值给alex这个变量(实例化);执行Person()函数后, return self;alex = self = {"names":name,"sexs":sex,"hps":hp,"ads":ad} jinmao = Dog("旺财","女",50,5) #程序第 2 步 #给Dog这个函数传参数,赋值给jinmao这个变量(实例化);执行Dog()函数后, return self;jinmao = self = {'name': name, 'kind':kind, 'hp': hp, 'ad': ad} alex["attack"](jinmao) #程序第 3 步 --->attack(jinmao) print(chen["hp"]) #查看狗的血量 #程序第 5 步
二、类(class)的定义和各个参数
class Person:
role = "person" #静态参数
def func(self): #动态属性 方法(默认带一个self参数)
print(1245)
(一).类名的作用:
__dict__ :查看class里面的所有属性,
1、引用静态变量:
方法1:类名.__dict__["静态变量名"]
可以查看,但是不能删改
print(Person.__dict__["role"])
print(Person.__dict__["role"] = "dog") #这样会报错
方法2:类名.静态变量名,直接就可以访问,可以删改(删除一个静态变量 用del)
print(Person.role) #"person"
print(Person.role = "dog") #"dog" 可以修改
del Person.role #直接将role = "person" 删除
2、引用动态参数:
1.类名.方法名 查看这个方法的内存地址
2.类名.方法名(实参)
调用了这个方法,必须传一个实参,给self
3、创造一个对象 ---> 实例化
1.产生一个实例(对象)的过程
2.对象 = 类名()
alex = Person() #创造一个对象
(二).class的__init__方法
__init__方法:
初始化方法,给一个对象添加一些基础属性的方法,一般情况下是针对self的赋值。
class Person:
role = "person" #静态属性
def __init__(self,name,sex,hp,ad): (self)#对象属性,属性
self.names = name
self.sexs = sex
self.hps = hp
self.ads = ad
def attack(self): #动态属性 方法
print("%s发起了一次攻击"%self.name)
alex = Person("sb","男",20,5)
alex.attack()
实例化的过程:
1.创造一个实例,将会作为一个实际参数
2.自动触发一个__init__方法,并且把实例以参数的形式传递给__init__方法中的self形参。
3.执行完__init__方法之后,会将self自定返回给对象

(三)、创建一个类(以及动态的创建一个类)
name = 'Foo' coutry = '中国' detail = lambda self,x:x+1 手动创建 :也是调用了type来创建 class Foo(object): country = '中国' def detail(self,x): return x+1 动态创建 type(name,(object,),{'county':'中国','detail':lambda self,x:x+1}) type中的第一个参数是类名 第二个参数的继承了哪些类 第三个参数,类中成员 总结:python的类默认都是有type来创建;一切皆对象,类是type的对象
三、对象
说明:对象和类的一个不同点:
在类中,用__dict__["静态变量名"]是不能修改的;
在对象中是可以,用__dict__[""] 是可以修改的。

(一)、在类的内部,self是本类的一个对象;
self在class内部生成一个空字典,在class内部开辟一个self自己的名称空间;
如果被实例化之后,self会指向一个新的对象。
(二)、在类的外部,每个对象都对应一个名字,这个对象指向一个对象的内存空间
def __init__(self,name,sex,hp,ad): (self)#对象属性,属性
属性的调用:
对象名.属性名 (alex.names) 第一种方法(习惯用第一种方法)
对象名.__dict__["属性名"] (alex.__dict__["names"]) 第二种方法
方法的调用:
类名.方法名(对象名) 方法中的self参数就指向这个对象
Person.attack(alex)
对象名.方法名() 这样写 相当于方法中的self参数直接指向这个对象
alex.attack() 是Person.attack(alex)的简化版。
四、对象之间的交互
创建两个不同的类:class1和class2 实例化两个对象:对象一和对象二。
将对象一作为参数,传递给class2类中的方法;再调用class2类的方法;
将对象二作为参数,传递给class1类中的方法;再调用class1类的方法;
从而实现对象的交互。
class Person: role = "preson" def __init__(self,name,sex,hp,ad): self.name = name self.sex = sex self.hp = hp self.ad = ad def attack(self,d): d.hp -= self.ad #why可以直接引用self.ad:实例化的过程最后将self返回给了对象(alex) print("%s攻击了%s,%s掉了%s滴血,还剩%s滴血" %(self.name,d.name,d.name,self.ad,d.hp)) #可以只用d.name;是因为把狗这个对象当参数,传给了attack方法 class Dog: role = "dog" def __init__(self,name,kind,hp,ad): self.name = name self.kind = kind self.hp = hp self.ad = ad def bite(self,p): p.hp -= self.ad print("%s咬了%s,%s掉了%s滴血,还剩%s滴血" %(self.name,p.name,p.name,self.ad,p.hp)) alex = Person("南审","男",100,10) jin = Person("金老板","男",100,20) jinmao = Dog("金毛","狗",100,5)
五、类名称空间与对象的名称空间
在调用方法时:Person.attack(alex) (通过class找到方法,在把对象当参数传给方法)
----> alex.attack() (由对象直接调用方法加()) 为什么可以这样简化?
(一)Person.attack(alex) 按照正常的顺序逻辑,依次执行。
(二)alex.attack() alex先找自己的内存空间-->再找到类对象指针-->再根据类对象指针找到类-->再通过类找到attack

总结:对象的内存空间,只存储对象的属性,而不存储方法和静态属性
类的内存空间,存储方法和静态属性,为了节省内存,让多个对象共享类中的资源。
练习题:
class Person: money = [0] def __init__(self,name): self.name = name def work(self): print(self.name,'工作,赚了1000块钱') Person.money = [Person.money[0] + 1000] father = Person('father') mother = Person('mother') mother.work() father.work() print(Person.money) #结果是2000
class Person: money = [0] def __init__(self,name): self.name = name def work(self): print(self.name,'工作,赚了1000块钱') self.money[0] += 1000 father = Person('father') mother = Person('mother') mother.work() father.work() print(Person.money) #结果是2000; 对于静态属性是可变数据类型;这里修改的money列表索引0对应的元素的值。
总结:
对象属性是独有的,静态属性和方法是共享的
对象使用名字:先找自己内存空间中的,再找类的内存空间中的
类名.静态变量名 :对于静态属性的修改,应该使用类名直接修改

浙公网安备 33010602011771号