zoukankan      html  css  js  c++  java
  • 封装、property特性及绑定与非绑定方法

    1、封装

    (1)什么是封装?

    封:属性对外是隐藏的,但对内是开放的;

    装:申请一个名称空间,往里面装入一系列名字/属性

    (2)为什么要封装?

    封装数据属性的目的

           首先定义属性的目的就是为了给类外部的使用者使用的

            隐藏之后是为了不让外部使用直接使用,需要类内部开辟一个接口

            然后让类外部的使用通过接口来间接的操作隐蔽的属性

            精髓在于:我们可以在接口之上附加任意逻辑,从而严格严格控制使用者对属性的操作;

    封装函数属性

             首先定义属性的目的就是为了给类外部的使用使用的

              隐藏函数属性是为了让使用者不直接使用,在类内部开辟一个接口,在接口内部调用隐蔽的功能

              精髓在于:隔离了复杂度

    (3)如何封装

    如何隐藏:在属性前加上__开头

    1、这种隐藏仅仅只是一种语法上的变形操作;

    2、这种语法上的变形只是在类定义阶段发生一次,因为类体代码仅仅只在类定义阶段检测一次;

    3、这种隐藏是对外不对内的,即在类的内部可以直接访问

    ,而在类的外部则无法直接访问,原因是在类定义阶段,类体代码统一发生了一次变形

    (4)、如果不想让子类的方法覆盖父类的,可以将该方法名前加上一个__开头

    如何隐藏
    # class people:
    # __country= 'china' # 在要隐藏的属性前加上__
    # 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 ) #在类内部可以访问

    # peo= people('egon',18,'male')
    #people .__country #在类外部无法访问
    # print(people.__dict__ )
    #隐藏的原理:在类定义阶段属性名__country 变成了_people__country
    # print(people._people__country) #这样是可以访问到隐藏后的属性的


    如果不想让子类的方法覆盖父类的,可以将该方法名前加上一个__开头

    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')
    #print(Bar.mro())
    obj = Bar()
    obj.f2()

    2、Property 装饰器

    property装饰器用于将被装饰的方法伪装成一个数据类型,在使用时不用加括号而直接引用

    class people:
    def __init__(self,name):
    self.__name= name

    @property #伪装成数据属性查看
    def name(self):
    return self .__name

    @name.setter #在原来函数name上进行修改操作
    def name(self,name):
    if type(name) is not str:
    print('名字必须是str类型')
    self .__name= name #把原来的属性self.__name改成name

    @name.deleter #删去操作
    def name(self):
    #print('不让删')
    del self.__name


    peo= people ('qqc') #建对象

    # print(peo.name) #查看
    peo.name= 'QQC' #修改操作
    print(peo.name)
    # del peo.name #删除操作
    # print(peo.__dict__ )

    3、绑定方法与非绑定方法

    (1)绑定方法

    特性:绑定给谁就应该由谁来调用,谁里啊调用就会将谁当做第一个参数自定传入

    注:自动传值

    绑定方法分为两类:

    1.1 绑定给对象的方法

               在类内部定义的函数(没有被任何装饰器修饰的),默认就是绑定给对象用的

    1.2 绑定给类的方法

               在类内部定义的函数如果被装饰器@classmethod装饰,

               那么则是绑定给类的,应该由类来调用,类来调用就自动将类当做第一个参数自动传入

    (2)非绑定方法

    类中定义的函数如果被装饰器@staticmethod装饰,那么该函数就变成非绑定方法

    即不与类绑定,又不与对象绑定,意味着类与对象都可以来调用

    但是无论谁来调用,都没有任何自动传值的效果,就是一个普通函数

    应用:

    函数体代码需要用外部传入的类,则应该将该函数定义成绑定给类的方法;

    函数体代码需要用外部传入的对象,则应该将该函数定义成绑定给对象的方法;

    如果函数体代码即不需要外部传入的类也不需要外部传入的对象,则应该将该函数定义成非绑定方法/普通函数

    #绑定方法
    class Foo:
    @classmethod
    def f1(cls):
    print(cls)
    def f2(self):
    print(self)

    obj = Foo()
    # print(obj.f2)
    #1、f1是绑定给类的,应该由类来调用,但其实对象也可以调用,但自动传入的参数仍然是类
    # Foo.f1()
    #2、f2是绑定给对象的
    # obj.f2()

    例子:从配置文件中实例化

    import settings
    class mysql:
    def __init__(self,ip,port):
    self.ip= ip
    self.port= port

    def tell_info(self):
    print(self.ip ,self .port)

    @classmethod
    def from_conf(cls): #与类绑定,自动传入类
    return mysql(settings.IP,settings.PORT)

    @staticmethod #非绑定方法,无自动传值
    def func():
    print('不与任何人绑定')

    #默认实例化方式:类名(。。。)
    obj= mysql('10.10.0.9',3307)

    #一种新的实例化方式,从配置文件中读取配置完成实例化
    obj1= mysql.from_conf()
    obj1.tell_info()
    obj1.func()
  • 相关阅读:
    run blackberry Sim&MDS4.7
    jsadd input name
    java memory
    silverlight Pivot Hearder
    eclipse tomcat server
    Monitor.Wait初探(5)
    Monitor.Wait初探(4)
    Monitor.Wait初探(2)
    解决远程注册表打不开,Cannot open HKEY_LOCAL_MACHIN…
    Windows界面自动化技术发展概要(二)
  • 原文地址:https://www.cnblogs.com/quqinchao/p/9239879.html
Copyright © 2011-2022 走看看