zoukankan      html  css  js  c++  java
  • python cookbook第三版学习笔记十五:property和描述

    8.5 私有属性:

    在python中,如果想将私有数据封装到类的实例上,有两种方法:1 单下划线。2 双下划线

    1 单下划线一般认为是内部实现,但是如果想从外部访问的话也是可以的

    2 双下划线是则无法通过外部访问且不能被继承覆盖

    来看下面的这个例子:

    class B:

        def __init__(self):

            self.__private=0

        def __private_method(self):

            print("__private method")

        def public_method(self):

            self.__private_method()

            print("public method")

    class C(B):

        def __init__(self):

            super().__init__()

            self.__private=2

        def __private_method(self):

            print("private_method in C")

        def public_method(self):

            self.__private_method()

            print("public method in C")

    if __name__=="__main__":

        b=B()

        b.public_method()

        c=C()

    c.public_method()

    运行结果:可以看到在C中虽然也申明了__private_method。但是B类中的函数并没有被C所覆盖

    __private method

    public method

    private_method in C

    public method in C

    8.6 可管理的属性:

    要自定义对属性的访问,一种简单的方式就是将其定义为property

    class Person():

        def __init__(self,name):

            self.first_name=name

        @property

        def name(self):

            return self.first_name

        @name.setter

        def name(self,name):

            if not isinstance(name,str):

                raise TypeError('Expected a string')

            self.first_name=name

        @name.deleter

        def name(self):

            raise AttributeError('can not delete attribute')

    通过对name进行property进行修饰,可以将name变成一个属性直接调用。在通过@name.setter就可以对属性进行赋值操作

    if __name__=="__main__":

        p=Person("abc")

        print(p.name)    

        p.name="zhf"

        print(p.name)

    del p.name

    运行结果:

    abc

    zhf

    Traceback (most recent call last):

      File "D:/py_prj/test2/cookbook.py", line 47, in <module>

        del p.name

      File "D:/py_prj/test2/cookbook.py", line 38, in name

        raise AttributeError('can not delete attribute')

    AttributeError: can not delete attribute

    下面来看一种新式的实例属性。可以用描述符类的形式定义功能。所谓的描述符就是用特殊方法__get__(),__set__(),__del__()。这些方法通过接受类示例作为输入来工作。

    class Integer:

        def __init__(self,name):

            self.name=name

        def __get__(self, instance, owner):

            if instance is None:

                return self

            else:

                return instance.__dict__[self.name]

        def __set__(self, instance, value):

            if not isinstance(value,int):

                raise TypeError('expect int')

            instance.__dict__[self.name]=value

        def __delete__(self, instance):

            del instance.__dict__[self.name]

    class Point():

        x=Integer('x')

        y=Integer('y')

        def __init__(self,x,y):

            self.x=x

            self.y=y

    在这里x,y和分别是Integer的实例化对象。但是通过描述符,我们可以把描述符的实例放置在类的定义中作为类变量来使用。当这么做的时候,所有针对描述符属性的访问都会被__get__(),.__set__()和__delete__方法捕获。

    比如调用self.x的时候其实调用的是Point.x__set__(p,x). 也就是说在Integer的__set__参数instance其实是Point的实例化对象。通过这种描述符的方法,我们就可以对类中的变量自动进行赋值以及类型判断。相比于使用property的方法。这种方法更加简洁

  • 相关阅读:
    adb 连接小米1S真机调试
    【Docker】容器中找不到vi命令
    【BIEE】导出数据报错
    【SPSS】软件介绍
    【Oracle】查询字段的长度、类型、精度、注释等信息
    【BIRT】使用rptlibrary设置统一数据源
    【Oracle】迁移含有BLOG类型的字段的表
    【Linux】war包的解压与压缩
    【docker】挂载web应用
    【Docker】安装tomcat并部署应用
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/9464889.html
Copyright © 2011-2022 走看看