zoukankan      html  css  js  c++  java
  • python-study-23

    学习总结

    封装:外部不能直接使用,内部开接口
    property:将方法伪装成数据,可以不加括号直接用
    绑定:绑定(对象,类),非绑定
    
    封装(方法,数据):
    1 数据封装 提供接口,附加逻辑
    2 方法封装 隔离复杂度
    
    property(方法):注意方法名一样
    property        查看
    name.setter   修改
    name.deleter  删除
    
    方法(绑定 非绑定):
    
    绑定:1 对象 默认  2 类 classmethod(配置文件读配置)
    非绑定: staticmethod   (uuid.uuid1())
    View Code

    复习

    上节课复习:
        1、组合
            什么是组合?
                一个类的对象具备某一个属性
                该属性的值是指向另外一个类的对象的
                class Foo:
                    pass
    
                class Bar:
                    pass
    
                obj_of_foo=Foo()
                obj_of_bar=Bar()
                obj_of_foo.attrib=obj_of_bar
    
                obj_of_foo.attrib.xxx
    
            为何用组合?
                是为了减少类与类直接的代码冗余
    
    
        2、菱形继承问题之新式类与经典的区别
            A(B,C,D)
            在属性查找方面
            新式类:广度优先查找
            经典类:深度优先查找
    
        3、继承的实现原理
            c3算法
            mro列表
        4、在子类派生的新方法中重用父类功能的两种方式
            指名道姓(与继承无关):类名.函数名(该传几个传几个)
            super(自己的类名,self).父类的属性:严格依赖继承,super()会得到一个特殊的对象
                                                该对象专门从当前的父类开始往后查找
    
    
        5、多态
            多态指的是同一种事物的多种形态,比如水有冰、水蒸气、雪
            多态性:
                指的是继承同一个父类的子类,具有相同的方法名
                在使用的时候,子类的对象可以在不用考虑其具体数据类型的前提下
                而直接调用的方法
            import abc
            class Foo(metaclass=abc.ABCMeta):
                @abc.abstractmethod
                def func1(self):
                    pass
    
            class Bar(Foo):
                def func1(self):
                    pass
    
            强调:父类不能实例化,子类要想实例化则必须实现与父类同名的方法
    
            python中崇尚“鸭子类型”
    
    
    今日内容:
        1、封装
            1.1 如何隐藏属性
            1.2 封装的真实意图与用法
            1.3 property
    
        2、绑定方法与非绑定方法
    View Code

    封装

    '''
    1、什么是封装
        封:属性对外是隐藏的,但对内是开放的
        装:申请一个名称空间,往里装入一系列名字/属性
    
    2、为什么要封装
        封装数据属性的目的
            首先定义属性的目的就是为了给类外部的使用使用的,
            隐藏之后是为了不让外部使用直接使用,需要类内部开辟一个接口
            然后让类外部的使用通过接口来间接地操作隐藏的属性。
            精髓在于:我们可以在接口之上附加任意逻辑,从而严格控制使用者对属性的操作
    
        封装函数属性
            首先定义属性的目的就是为了给类外部的使用使用的,
            隐藏函数属性是为了不让外不直接使用,需要类内部开辟一个接口
            然后在接口内去调用隐藏的功能
            精髓在于:隔离了复杂度
    
    
    
    3、如何封装
    
    '''
    # 如何隐藏:在属性前加上__开头
    
    
    #1、 这种隐藏仅仅只是一种语法上的变形操作
    #2、 这种语法上的变形只在类定义阶段发生一次,因为类体代码仅仅只在类定义阶段检测一次
    #3、 这种隐藏是对外不对内的,即在类的内部可以直接访问,而在类的外则无法直接访问,原因是
    #    在类定义阶段,类体内代码统一发生了一次变形
    
    #4、 如果不想让子类的方法覆盖父类的,可以将该方法名前加一个__开头
    
    
    # class People:
    #     __country='China' #_People__country='China'
    #     __n=100 #_People__n=100
    #     def __init__(self,name,age,sex):
    #         self.__name=name #self._People__name=name
    #         self.age=age
    #         self.sex=sex
    #
    #     def eat(self):
    #         print('eat.....')
    #         print(People.__country) #People._People__country
            # print(self.__name) #self._People__name
    
    # People.eat(123)
    # print(People.__country)
    
    # peo1=People('egon',18,'male')
    # peo1.eat()
    # print(peo1.__name)
    
    # print(People.__dict__)
    # print(People.__country)
    # print(People._People__country)
    
    # People.__x=11
    # print(People.__dict__)
    
    
    # peo1=People('egon',18,'male')
    # print(peo1.__dict__)
    # peo1.__x=111
    # print(peo1.__dict__)
    
    # class Foo:
    #     def __f1(self): #_Foo__f1
    #         print('Foo.f1')
    #
    #     def f2(self):
    #         print('Foo.f2')
    #         self.__f1() #self._Foo__f1
    #
    # class Bar(Foo):
    #     def __f1(self): #_Bar__f1
    #         print('Bar.f1')
    #
    # obj=Bar()
    # obj.f2()
    
    
    # class People:
    #     def __init__(self,name,age):
    #         self.__name=name
    #         self.__age=age
    #
    #     def tell_info(self):
    #         print('%s:%s' %(self.__name,self.__age))
    #
    #     def set_info(self,name,age):
    #         if type(name) is not str:
    #             # print('用户名必须为str类型')
    #             # return
    #             raise TypeError('用户名必须为str类型')
    #
    #         if type(age) is not int:
    #             # print('年龄必须为int类型')
    #             # return
    #             raise TypeError('年龄必须为int类型')
    #         self.__name=name
    #         self.__age=age
    #
    # peo1=People('egon',18)
    # peo1.name=123
    # peo1.age
    # peo1.tell_info()
    #
    # peo1.set_info('egon',19)
    # peo1.tell_info()
    View Code

    特性

    #property装饰器用于将被装饰的方法伪装成一个数据属性,在使用时可以不用加括号而直接引用
    # class People:
    #     def __init__(self,name,weight,height):
    #         self.name=name
    #         self.weight=weight
    #         self.height=height
    #
    #     @property
    #     def bmi(self):
    #         return self.weight / (self.height ** 2)
    #
    # peo1=People('egon',75,1.8)
    #
    # peo1.height=1.85
    # print(peo1.bmi)
    
    
    '''
    class People:
        def __init__(self,name):
            self.__name=name
    
        @property # 查看obj.name
        def name(self):
            return '<名字是:%s>' %self.__name
    
        @name.setter #修改obj.name=值
        def name(self,name):
            if type(name) is not str:
                raise TypeError('名字必须是str类型傻叉')
            self.__name=name
    
        @name.deleter #删除del obj.name
        def name(self):
            # raise PermissionError('不让删')
            print('不让删除傻叉')
            # del self.__name
    
    peo1=People('egon')
    # print(peo1.name)
    
    # print(peo1.name)
    
    # peo1.name='EGON'
    # print(peo1.name)
    
    del peo1.name
    
    '''
    
    
    class People:
        def __init__(self,name):
            self.__name=name
    
    
        def tell_name(self):
            return '<名字是:%s>' %self.__name
    
        def set_name(self,name):
            if type(name) is not str:
                raise TypeError('名字必须是str类型傻叉')
            self.__name=name
    
        def del_name(self):
            print('不让删除傻叉')
    
        name=property(tell_name,set_name,del_name)
    
    
    peo1=People('egon')
    
    print(peo1.name)
    peo1.name='EGON'
    print(peo1.name)
    del peo1.name
    View Code

    绑定方法与非绑定方法

    '''
    1、绑定方法
        特性:绑定给谁就应该由谁来调用,谁来调用就会将谁当作第一个参数自动传入
             《《《精髓在于自动传值》》》
    
        绑定方法分为两类:
            1.1 绑定给对象方法
                在类内部定义的函数(没有被任何装饰器修饰的),默认就是绑定给对象用的
            1.2 绑定给类的方法:
                在类内部定义的函数如果被装饰器@classmethod装饰,
                那么则是绑定给类的,应该由类来调用,类来调用就自动将类当作第一个参数自动传入
    
    2、非绑定方法
        类中定义的函数如果被装饰器@staticmethod装饰,那么该函数就变成非绑定方法
        既不与类绑定,又不与对象绑定,意味着类与对象都可以来调用
        但是无论谁来调用,都没有任何自动传值的效果,就是一个普通函数
    
    3 应用
        如果函数体代码需要用外部传入的类,则应该将该函数定义成绑定给类的方法
        如果函数体代码需要用外部传入的对象,则应该将该函数定义成绑定给对象的方法
        如果函数体代码既不需要外部传入的类也不需要外部传入的对象,则应该将该函数定义成非绑定方法/普通函数
    
    
    '''
    
    # class Foo:
    #     @classmethod
    #     def f1(cls):
    #         print(cls)
    #
    #     def f2(self):
    #         print(self)
    
    
    # obj=Foo()
    # print(obj.f2) #obj
    # print(Foo.f1) #Foo
    #
    # Foo.f1()
    # print(Foo)
    
    
    #1、f1绑定给类的
    # 了解:绑定给类的应该由类来调用,但对象其实也可以使用,只不过自动传入的仍然是类
    # print(Foo.f1)
    # print(obj.f1)
    # Foo.f1()
    # obj.f1()
    
    #2、f2是绑定给对象的
    # obj.f2()
    # Foo.f2(obj)
    
    import settings
    import uuid
    
    class Mysql:
        def __init__(self,ip,port):
            self.uid=self.create_uid()
            self.ip=ip
            self.port=port
    
        def tell_info(self):
            print('%s:%s' %(self.ip,self.port))
    
        @classmethod
        def from_conf(cls):
            return cls(settings.IP, settings.PORT)
    
        @staticmethod
        def func(x,y):
            print('不与任何人绑定')
    
        @staticmethod
        def create_uid():
            return uuid.uuid1()
    
    # 默认的实例化方式:类名(..)
    obj=Mysql('10.10.0.9',3307)
    
    # 一种新的实例化方式:从配置文件中读取配置完成实例化
    obj1=Mysql.from_conf()
    obj1.tell_info()
    
    obj.func(1,2)
    Mysql.func(3,4)
    print(obj.func)
    print(Mysql.func)
    
    print(obj.uid)
    View Code
    1、定义MySQL类(参考答案:http://www.cnblogs.com/linhaifeng/articles/7341177.html#_label5)
    
      1.1.对象有id、host、port三个属性
    
      1.2.定义工具create_id,在实例化时为每个对象随机生成id,保证id唯一
    
      1.3.提供两种实例化方式,方式一:用户传入host和port 方式二:从配置文件中读取host和port进行实例化
    
      1.4.为对象定制方法,save和get_obj_by_id,save能自动将对象序列化到文件中,文件路径为配置文件中DB_PATH,文件名为id号,保存之前验证对象是否已经存在,若存在则抛出异常,;get_obj_by_id方法用来从文件中反序列化出对象
    
    2、定义一个类:圆形,该类有半径,周长,面积等属性,将半径隐藏起来,将周长与面积开放
        参考答案(http://www.cnblogs.com/linhaifeng/articles/7340801.html#_label4)
    
    
    3、明日默写
        1、简述面向对象三大特性:继承、封装、多态
        2、定义一个人的类,人有名字,身高,体重,用property讲体质参数封装成人的数据属性
        3、简述什么是绑定方法与非绑定方法,他们各自的特点是什么?
    作业
    ###1 author--oneself
    import settings
    import uuid
    import json
    import os
    
    class Mysql:
        def __init__(self,host,port):
            self.uid=self.create_uid()
            self.host=host
            self.port=port
    
        @staticmethod  #为每个对象随机生成id
        def create_uid():
            return uuid.uuid1()
    
        @classmethod
        def from_conf(cls): #从配置文件中读取host和port进行实例化
            return cls(settings.HOST, settings.PORT)
    
        def save(self):
            user_dic = {'host':self.host,'port':self.port}
            user_path = os.path.join(settings.DB_PATH,'%s.json' %self.uid)
            if os.path.exists(user_path):
                raise FileExistsError('文件已存在')
            with open(user_path,'w',encoding='utf-8') as f:
                json.dump(user_dic,f)
                f.flush()
                print('save successful')
    
        # def get_obj_by_id(self):
        #     user_path = os.path.join(settings.DB_PATH, '%s.json' % self.uid)
        #     with open(user_path,encoding='utf-8') as f:
        #         return json.load(f)
    
        @staticmethod
        def get_obj_by_id(id):
            user_path = os.path.join(settings.DB_PATH,id)
            with open(user_path,encoding='utf-8') as f:
                return json.load(f)
    
    # mysql1 = Mysql.from_conf()
    # mysql2 = Mysql('3.3.3.3','88')
    #
    # mysql1.save()
    # mysql2.save()
    
    # print(mysql1.get_obj_by_id())
    # print(mysql2.get_obj_by_id())
    
    obj1 = Mysql.get_obj_by_id('2d197874-7ac6-11e8-915c-68f728b8340c.json')
    print(obj1)
    
    
    
    
    
    
    ###2
    # import math
    #
    #
    # class circle:  # radius   #perimeter   #area
    #     def __init__(self, radius):
    #         self.__radius = radius
    #
    #     @property
    #     def perimeter(self):
    #         return 2 * math.pi * self.__radius
    #     @property
    #     def area(self):
    #         return math.pi * self.__radius ** 2
    #
    # c1 = circle(3)
    # print(c1.perimeter)
    # print(c1.area)
    
    ##1
    # 继承:新建类,遗传属性,减少代码冗余,新式类,经典类
    # 封装:对内开放,对外隐藏,外部不能直接使用,调用接口,附加逻辑,隔离复杂度
    # 多态:同一事物,不通形态,同一父类的子类,相同的方法名, 使用时子类的对象可以在不用考虑其具体数据类型的前提下,直接调用方法
    
    ##2
    # class People:
    #     def __init__(self,name,height,weight):
    #         self.name=name
    #         self.height=height
    #         self.weight=weight
    #
    #     @property
    #     def bmi(self):
    #         return self.weight / (self.height ** 2)
    #
    # p1 = People('xjj',1.78,68)
    # print(p1.bmi)
    
    ##3
    # 绑定方法:自动传值   1 对象绑定(默认) 2 类绑定(@classmethod)
    # 非绑定方法: 没有自动传值 @staticmethod 普通函数,都可以调用
    View Code
  • 相关阅读:
    [翻译] GCDObjC
    [翻译] ValueTrackingSlider
    [翻译] SWTableViewCell
    使用 NSPropertyListSerialization 持久化字典与数组
    [翻译] AsyncImageView 异步下载图片
    KVC中setValuesForKeysWithDictionary:
    [翻译] Working with NSURLSession: AFNetworking 2.0
    数据库引擎
    什么是数据库引擎
    网站添加百度分享按钮代码实例
  • 原文地址:https://www.cnblogs.com/xujinjin18/p/9240222.html
Copyright © 2011-2022 走看看