美文网首页
Python ☞ day 8

Python ☞ day 8

作者: 浪子彦卿L | 来源:发表于2018-05-09 00:33 被阅读0次

    Python学习笔记之 面向对象

    第一个python类
    • 设计类
      类名:见名之意,首字母大写,其他遵循驼峰原则
      属性:见名之意,其他遵循驼峰原则
      行为(方法/功能):见名之意,其他遵循驼峰原则
    • 列如:
    1. 类名:Wife
      属性:sex age height weight faceValue
      行为:做饭 洗衣服 拖地 揉肩 捶腿
    2. 类名:Husband
      属性:sex age height weight faceValue
      行为:吃饭 看电视 打游戏 被揉肩 被捶腿
    3. 类名:Car
      属性: color type
      行为:跑
    • 创建类
      类:一种数据类型,本身并不占内存空间,根所学过的number,string,boolean等类似。用类创建实例化对象(变量),对象占内存空间
    格式:
    class  类名(父类列表):
        属性
        行为
    
    #            object:基类,超类,所有类的父类,一般没有合适的父类就写object
    class Person(object):
        #定义属性(定义变量)
        name = ""
        age = 0
        height = 0
        weight = 0
    
        #定义方法(定义函数)
        #注意:方法的参数必须以self当第一个参数
        #self代表类的实例(某个对象)
        def run(self):
            print("run")
        def eat(self, food):
            print("eat" + food)
    
    使用类实例化对象
    • 实例化对象
      格式: 对象名 = 类名(参数列表)
      注意:没有参数,小括号也不能省略
    class Person(object):
        name = ""
        age = 0
        height = 0
        weight = 0
        def run(self):
            print("run")
        def eat(self, food):
            print("eat" + food)
        def openDoor(self):
            print("我已经打开了冰箱门")
        def fillEle(self):
            print("我已经把大象装进冰箱了")
        def closeDoor(self):
            print("我已经关闭了冰箱门")
    
    
    #实例化一个对象
    per1 = Person()
    print(per1)
    print(type(per1))
    print(id(per1))
    
    per2 = Person()
    print(per2)
    print(type(per2))
    print(id(per2))
    
    访问对象的属性和方法
    • 访问属性
      格式:对象名.属性名
      赋值:对象名.属性名 = 新值
    class Person(object):
        name = "stu"
        age = 10
        height = 160
        weight = 90
        def run(self):
            print("run")
        def eat(self, food):
            print("eat " + food)
        def openDoor(self):
            print("我已经打开了冰箱门")
        def fillEle(self):
            print("我已经把大象装进冰箱了")
        def closeDoor(self):
            print("我已经关闭了冰箱门")
    
    
    per = Person()
    
    per.name = "tom"
    per.age = 18
    per.height = 160
    per.weight = 80
    print(per.name, per.age, per.height, per.weight)
    
    • 访问方法
      格式:对象名.方法名(参数列表)
    class Person(object):
       name = "stu"
       age = 10
       height = 160
       weight = 90
       def run(self):
           print("run")
       def eat(self, food):
           print("eat " + food)
       def openDoor(self):
           print("我已经打开了冰箱门")
       def fillEle(self):
           print("我已经把大象装进冰箱了")
       def closeDoor(self):
           print("我已经关闭了冰箱门")
    
    
    per = Person()
    
    per.openDoor()
    per.fillEle()
    per.closeDoor()
    
    per.eat("apple")
    
    
    
    #问题:目前来看Person创建的所有对象属性都是一样的
    per2 = Person()
    print(per2.age)
    per3 = Person()
    print(per3.age)
    
    对象的初始状态(构造函数)
    构造函数:__init__()   在使用类创建对象的时候自动调用
    注意:如果不显示的写出构造函数,默认会自动添加一个空的构造函数
    
    class Person(object):
        #name = "stu"
        #age = 10
        #height = 160
        #weight = 90
        def run(self):
            print("run")
        def eat(self, food):
            print("eat " + food)
    
        def __init__(self, name, age, height, weight):
            #print(name, age, height, weight)
            #定义属性
            self.name = name
            self.age = age
            self.height = height
            self.weight = weight
    
    
    per = Person("hanmeimei", 20, 170, 55)
    print(per.name, per.age)
    
    per2 = Person("lilei", 21, 175, 70)
    print(per2.name, per2.age)
    
    per.run()
    
    self
    • self代表类的实例,而非类
      哪个对象调用方法,那么该方法中的self就代表那个对象
    self.__class__  代表类名_
    
    class Person(object):
        def run(self):
            print("run")
            print(self.__class__)
            p = self.__class__("tt", 30, 10, 30)
            print(p)
        def eat(self, food):
            print("eat " + food)
        def say(self):
            print("Hello! my name is %s, I am %d years old" % (self.name, self.age))
        #self不是关键字,换成其他的标识符也是可以的,但是帅的人都是用self
        def play(a):
            print("play " + a.name)
        def __init__(self, name, age, height, weight):
            self.name = name
            self.age = age
            self.height = height
            self.weight = weight
    
    per1 = Person("tom", 20, 160, 80)
    per1.say()
    
    per2 = Person("hanmeimei", 21, 160, 80)
    per2.say()
    
    
    per1.play()
    
    per1.run()
    
    析构函数
    析构函数:__del__()    释放对象是自动调用
    
    class Person(object):
        def run(self):
            print("run")
        def eat(self, food):
            print("eat " + food)
        def __init__(self, name, age, height, weight):
            self.name = name
            self.age = age
            self.height = height
            self.weight = weight
        def __del__(self):
            print("这里是析构函数")
    
    per = Person("hanmeimei", 20, 170, 55)
    #释放对象
    del per
    
    #对象释放以后就不能再访问了
    #print(per.age)
    
    
    #在函数里定义的对象,会在函数结束时自动释放,这样可以用来减少内存空间的浪费
    def func():
        per2 = Person("aa", 1, 1, 1)
    
    func()
    
    while 1:
        pass
    
    重写:将函数重写定义写一遍
    __str__():在调用print打印对象时自动调用,是给用户用的,是一个描述对象的方法。
    __repr__():是给机器用的,在Python解释器里面直接敲对象名在回车后调用的方法
    注意:在没有str时,且有repr,str = repr
    class Person(object):
        def __init__(self, name, age, height, weight):
            self.name = name
            self.age = age
            self.height = height
            self.weight = weight
        def __str__(self):
            return "%s-%d-%d-%d" % (self.name, self.age, self.height, self.weight)
    
    
    per = Person("hanmeimei", 20, 170, 55)
    #print(per.name, per.age, per.height, per.weight)
    print(per)
    
    优点:当一个对象的属性值很多,并且都需要打印,重写了__str__方法后,简化了代码
    
    访问限制
    class Person(object):
        def run(self):
            print(self.__money)
            print("run")
        def eat(self, food):
            print("eat " + food)
        def __init__(self, name, age, height, weight, money):
            self.name = name
            self.__age__ = age
            self._height = height
            self.weight = weight
            self.__money = money#_Person__money
    
        #通过内部的方法,取修改私有属性
        #通过自定义的方法实现对私有属性的赋值与取值
        def setMoney(self, money):
            #数据的过滤
            if money < 0:
                money = 0
            self.__money = money
        def getMoney(self):
            return self.__money
    
    
    per = Person("hanmeimei", 20, 170, 55, 100000)
    #per.age = 10
    #print(per.age)
    
    #如果要让的内部属性不被外部直接访问,在属性前加两个下划线(__),在Python中如果在属性前加两个下划线,那么这个属性就变成了私有属性
    #print(per.__money)  #外部使用
    #per.run()   #内部可以使用
    
    per.setMoney(10)
    print(per.getMoney())
    
    #不能直接访问per.__money是因为Python解释器把__money变成了_Person__money,仍然可以用_Person__money去访问,但是强烈建议不要这么干(帅的人都不这么干),不同的解释器可能存在解释的变量名不一致
    per._Person__money = 1
    print(per.getMoney())
    
    
    
    #在Python中  __XXX__   属于特殊变量,可以直接访问
    print(per.__age__)
    
    
    #在Python中  _XXX  变量,这样的实例变量外部是可以访问的,但是,按照约定的规则,当我们看到这样的变量时,意思是“虽然我可以被访问,但是请把我视为私有变量,不要直接访问我”
    print(per._height)
    
    单继承的实现
    # 定义第一个类:
    class Person(object):
        def __init__(self, name, age, money):
            self.name = name
            self.age = age
            self.__money = money
    
        def setMoney(self, money):
            self.__money = money
        def getMoney(self):
            return self.__money
    
        def run(self):
            print("run")
    
        def eat(self, food):
            print("eat " + food)
    
    
    
    # 定义第一个继承类
    from person import Person  #引入Person类
    
    class Student(Person):
        def __init__(self, name, age, money, stuId):
            #调用父类中的__init__
            super(Student, self).__init__(name, age, money)
            #子类可以有一些自己独有的属性
            self.stuId = stuId
    
        def stuFunc(self):
            print(self.__money)
    
    
    
    # 定义第二个继承类
    from person import Person
    
    class Worker(Person):
        def __init__(self, name, age, money):
            #调用父类中的__init__
            super(Worker, self).__init__(name, age, money)
    
    
    
    # 单继承的实现
    from person import Person
    from student import Student
    from worker import Worker
    
    per = Person("aa", 1, 2)
    
    
    stu = Student("tom", 18, 12345, 110)
    print(stu.name, stu.age)
    stu.run()
    print(stu.stuId)
    #print(stu.__money)私有属性
    print(stu.getMoney())  #通过继承过来的共有方法访问私有属性
    #stu.stuFunc()
    
    
    wor = Worker("lilei", 20, 111)
    print(wor.name, wor.age)
    wor.eat("apple")
    
    
    print(per.getMoney())
    
    
    多继承的实现
    # 定义一个母亲类
    class Mother(object):
        def __init__(self, faceValue):
            self.faceValue = faceValue
        def eat(self):
            print("eat")
        def func(self):
            print("func2")
    
    
    # 定义一个父亲类
    class Father(object):
        def __init__(self, money):
            self.money = money
        def play(self):
            print("play")
        def func(self):
            print("func1")
    
    
    
    # 定义一个小孩类
    from Father import Father
    from Mother import Mother
    
    class Child(Father, Mother):
        def __init__(self, money, faceValue):
            #写法
            Father.__init__(self, money)
            Mother.__init__(self, faceValue)
    
    
    
    # 多继承的实现   调用
    from Child import Child
    
    def main():
        c = Child(300, 100)
        print(c.money, c.faceValue)
        c.play()
        c.eat()
        #注意:父类中方法名相同,默认调用的是在括号中排前面的父类中的方法
        c.func()
    if __name__ == "__main__":
        main()
    
    
    多态
    # 定义一个动物类
    class Animal(object):
        def __init__(self, name):
            self.name = name
        def eat(self):
            print(self.name + "吃")
    
    
    # 定义一个猫类
    from animal import Animal
    class Cat(Animal):
        def __init__(self, name):
            #self.name = name
            super(Cat, self).__init__(name)
        # def eat(self):
        #     print(self.name + "吃")
    
    
    # 定义一个老鼠类
    from animal import Animal
    class Mouse(Animal):
        def __init__(self, name):
            #self.name = name
            super(Mouse, self).__init__(name)
        # def eat(self):
        #     print(self.name + "吃")
    
    
    # 定义一个人类
    class Person(object):
        '''
        def feedCat(self, cat):
            print("给你食物")
            cat.eat()
        def feedMouse(self, mouse):
            print("给你食物")
            mouse.eat()
        '''
        def feedAnimal(self, ani):
            print("给你食物")
            ani.eat()
    
    
    # 多态        -    及调用
    from cat import Cat
    from mouse import Mouse
    from person import Person
    '''
    多态:一种事物的多种形态
    
    最终目标:人可以喂任何一种动物
    '''
    
    tom = Cat("tom")
    jerry = Mouse("jerry")
    
    tom.eat()
    jerry.eat()
    
    #思考:在添加100种动物,也都有name属性和eat方法
    #定义了一个有name属性和eat方法的Animal类,让所有的动物类都继承自Animal
    
    
    
    #定义一个人类,可以喂猫和老鼠吃东西
    per = Person()
    
    #per.feedCat(tom)
    #per.feedMouse(jerry)
    
    
    #思考:人要喂100种动物,难道要写100个feed方法吗??
    #tom和jerry都继承自动物
    per.feedAnimal(tom)
    per.feedAnimal(jerry)
    
    
    对象属性与类属性
    
    class Person(object):
        # 这里的属性实际上属于类属性(用类名来调用)
        name = "person"
        def __init__(self, name):
            pass
            #对象属性
            self.name = name
    
    
    print(Person.name)
    per = Person("tom")
    #对象属性的优先级高于类属性
    print(per.name)
    #动态的给对象添加对象属性
    per.age = 18#只针对于当前对象生效,对于类创建的其他对象没有作用
    print(Person.name)
    per2 = Person("lilei")
    #print(per2.age)  #没有age属性
    
    
    #删除对象中的name属性,在调用会使用到同名的类属性
    del per.name
    print(per.name)
    
    #注意:以后千万不要讲对象属性与类属性重名,因为对象属性会屏蔽掉类属性。但是当删除对象属性后,在使用又能使用类属性了。
    
    
    
    动态给实例添加属性和方法并使用__slots__
    from types import MethodType
    
    #创建一个空类
    class Person(object):
        __slots__ = ("name", "age", "speak")
    
    
    per = Person()
    #动态添加属性,这体现了动态语言的特点(灵活)
    per.name = "tom"
    print(per.name)
    #动态添加方法
    '''
    def say(self):
        print("my name is " + self.name)
    per.speak = say
    per.speak(per)
    '''
    def say(self):
        print("my name is " + self.name)
    per.speak = MethodType(say, per)
    per.speak()
    
    
    #思考:如果我们想要限制实例的属性怎么办?
    #比如,只允许给对象添加name,age,height,weight属性
    
    
    #解决:定义类的时候,定义一个特殊的属性(__slots__),可以限制动态添加的属性
    
    per.height = 170
    print(per.height)
    
    
    class Person(object):
        def __init__(self, name, age):
            #属性直接对外暴露
            #self.age = age
            #限制访问
            self.__age = age
            self.__name = name
    
        def getAge(self):
            return self.__age
        def setAge(self, age):
            if age < 0:
                age = 0
            self.__age = age
    
        #方法名为受限制的变量去掉双下划綫
        @property
        def age(self):
            return self.__age
        @age.setter  #去掉下划线.setter
        def age(self, age):
            if age < 0:
                age = 0
            self.__age = age
    
        @property
        def name(self):
            return self.__name
        @name.setter  # 去掉下划线.setter
        def name(self, name):
            self.__name = name
    
    
    per = Person("sunck", 18)
    
    #属性直接对外暴露
    #不安全,没有数据的过滤
    #per.age = -10
    #print(per.age)
    
    
    #使用限制访问,需要自己写set和get方法才能访问
    #per.setAge(15)
    #print(per.getAge())
    
    per.age = -100 #相当于调用setAage
    print(per.age) #相当于调用getAge
    
    print(per.name)
    
    #property:可以让你对受限制访问的属性使用点语法
    
    • 人开枪射击子弹练习
    # 定义一个弹夹类
    class BulletBox(object):
        def __init__(self, count):
            self.bulletCount = count
    
    
    
    # 定义一个枪类
    class Gun(object):
        def __init__(self, bulletBox):
            self.bulletBox = bulletBox
        def shoot(self):
            if self.bulletBox.bulletCount == 0:
                print("没有子弹了")
            else:
                self.bulletBox.bulletCount -= 1
                print("剩余子弹:%d发" % (self.bulletBox.bulletCount))
    
    
    
    # 定义一个人类
    class Person(object):
        def __init__(self, gun):
            self.gun = gun
        def fire(self):
            self.gun.shoot()
        def fillBullet(self, count):
            self.gun.bulletBox.bulletCount = count
    
    
    
    # 调用
    from person import Person
    from gun import Gun
    from bulletbox import BulletBox
    
    '''
    人
    类名:Person
    属性:gun
    行为:fire
    
    
    枪
    类名:Gun
    属性:bulletBox
    行为:shoot
    
    弹夹
    类名:BulletBox
    属性:bulletCount
    行为:
    '''
    
    
    #弹夹
    bulletBox = BulletBox(5)
    
    #枪
    gun = Gun(bulletBox)
    
    #人
    per = Person(gun)
    
    
    per.fire()
    per.fire()
    per.fire()
    per.fire()
    per.fire()
    
    per.fire()
    per.fire()
    
    per.fillBullet(2)
    per.fire()
    per.fire()
    per.fire()
    
    
    执行调用这个程序得到结果:
    剩余子弹:4发
    剩余子弹:3发
    剩余子弹:2发
    剩余子弹:1发
    剩余子弹:0发
    没有子弹了
    没有子弹了
    剩余子弹:1发
    剩余子弹:0发
    没有子弹了
    
    

    相关文章

      网友评论

          本文标题:Python ☞ day 8

          本文链接:https://www.haomeiwen.com/subject/xbmgrftx.html