zoukankan      html  css  js  c++  java
  • 类的封装,property装饰器的作用,绑定方法与非绑定方法,反射,

    类的封装

    '''
    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()
    封装,为什么封装

    property装饰器的作用

    # 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
    property

    绑定方法与非绑定方法

    '''
    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)
    # print(Foo.f1)
    
    # 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)
    绑定与非绑定

    反射

    什么是反射
        通过字符串来操作类或者对象的属性
    

      

    # d = {'name': '123'}
    # print(isinstance(d,dict))  # 是不是同一类型
    # class Foo:
    #     pass
    # class Bar(Foo):
    #     pass
    #
    # print(issubclass(Bar,Foo))   # Bar 是不是Foo的子类
    #
    #
    # class People:
    #     def __init__(self, name, ip, port):
    #         self.name = name
    #         self.ip = ip
    #         self.port = port
    #
    #
    #     def get(self):
    #         print('GET function')
    #
    #     def see(self):
    #         print('SEE function')
    #
    #     def run(self):
    #         while True:
    #             chioce = input(">>>>>>").strip()
    #             if hasattr(self, chioce):
    #                 monthod = getattr(self, chioce)
    #                 monthod()
    #             else:
    #                 print("没有这个命令")
    
    #             monthod = getattr(self,chioce, None)
    #             if monthod is None:
    #                 print('没有这个命令')
    #             else:
    #                 monthod()
    #
    # #
    #
    #
    # peo1 =People('egon', '12','222.10')
    # hasattr(peo1,'see')  # 有没有这个属性  有就返回True
    # getattr(peo1,'see',None)  # 给我这个属性, 没有就返回None
    # setattr(peo1,'name','alex')  # 改掉这个特征
    # delattr(peo1,'name')   # 删除这个属性 , 只能删除特征,不能删除函数
    # print(hasattr(peo1,'run'))
    
    
    # class People:
    #     def __init__(self, name, age):
    #         self.name = name
    #         self.age = age
    #
    #     def __str__(self):  # 自动触发,在打印时
    #         return '%s	%s' % (self.name, self.age)
    #
    #
    # peop1 = People('egon', '18')
    # peop2 = People('alex', '81')
    # print(peop1)
    # print(peop2)
    
    
    # class People:
    #     def __init__(self, name, age):
    #         self.name = name
    #         self.age = age
    #         self.f = open(r'a.txt', 'rt', encoding='utf-8')
    #
    #     def __del__(self):
    #         # del 在回收python文件时自动触发,把不属于python的资源也一起关闭,相当于临终遗言
    #         print('>>>>>>')
    #         self.f.close()
    #
    #
    # obj = People('egon', 18)
    #
    # print(123)
    反射的几种使用方法和内置的python方法
  • 相关阅读:
    上传图片并压缩
    一张图教会你es6
    字符串生成二维码
    city-picker城市选择,三级联动
    jquery本地文件
    前端颜色选择器
    某音乐api
    js正则那些事
    Android判断网络是否打开,并打开设置网络界面
    execute、executeQuery和executeUpdate之间的区别 转
  • 原文地址:https://www.cnblogs.com/xiejintao0914/p/9253838.html
Copyright © 2011-2022 走看看