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  步
View Code

二、类(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
View Code
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对应的元素的值。
View Code

总结:

  对象属性是独有的,静态属性和方法是共享的
  对象使用名字:先找自己内存空间中的,再找类的内存空间中的
  类名.静态变量名 :对于静态属性的修改,应该使用类名直接修改

posted @ 2018-04-13 14:44  纸上得来终觉浅,  阅读(171)  评论(0)    收藏  举报