我们都知道Python是一个弱类型语言,就是变量,参数无需自己定义类型,用过JAVA的同学应该知道两者之间的区别。下面我们看一个例子

Person:
    (,name,age,weight):
        .name = name
        .age = age
        .weight = weight

lei  = Person(,,)
ming = Person(,,)

(%(lei.name,lei.age,lei.weight))
(%(ming.name,ming.age,ming.weight))



结果:

我叫李雷,我今年18岁,身高173
我叫小明,我今年19岁,身高180cm


我们看看按道理说name应该是字符串类型,age应该是int类型,weight应该是浮点类型的,但是上面的案例,我们各自参数无论你传入上面样类型的值,都不会报错,正常打印出来。



那今天我们要讲的就是使用python中的描述符功能实现这些类型的检查,保证name必须是字符串,age必须是int, weight必须是浮点型,如果传入错误的类型,程序会出错。



  1. 什么是python的描述符


    这边主要是三个内置函数__get__(),__set__(),__delete__()

    __get__():调用一个属性时触发
    __set__():为属性赋值时触发
    __delete__():del删除属性时触发

   

 描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个



  2. 描述符的种类

  1)数据描述符

  至少实现了__get__()和__set__()

  2)非数据描述符

  没有实现__set__()

具体什么意思我们下面来说。


  3. 描述符是干什么的

描述符的作用是用来代理另外一个类的属性的,实现在实例调用,设置,删除属性之前,触发我们的代理,从而触发描述符中的__get__(),__set__(),__delete__()方法


 4.优先级

1.类属性
2.数据描述符
3.实例属性
4.非数据描述符
5.找不到的属性触发__getattr__()



下面我们就具体代码例子用数据描述符实现我们上面要实现的参数类型限制


Descriptor:
    (,name,expected_type):
        .name = name   .expected_type =expected_type  (,instance,value):
        ()  (,instance)
        (, value)

        instance.[.name]


    (,instance,value):
        ()
        (, instance)
        (, value)

        (value,.expected_type):
            (% (value,.expected_type))
        instance.[.name] = value

    (,instance):
        ()
        (, instance)

        instance..pop(.name)


Person:

    name = Descriptor(,)
    age = Descriptor(,)
    weight = Descriptor(,)

    (,name,age,weight):
        .name = name
        .age = age
        .weight = weight


lei  = Person(,,)


(%(lei.name,lei.age,lei.weight))




所有的解释说明都在代码里面,大家自行查看,上面我们实例化

lei  = Person('李雷',18,173.0)

这完全符合我们设置的参数类型,所有不会报错,但是如果我们传入错误的参数类型,如:

lei  = Person('李雷','18',173.0)


结果:


TypeError: 参数 18 的Expected Type is <class 'int'>


这里就起到了类型限制的作用。




下面说下非数据描述符,看看有什么不同

Descriptor:
    (,name,expected_type):
        .name = name
        .expected_type =expected_type

    (,instance,value):
        ()
        (,instance)
        (, value)
        instance.[.name]

Person:
    name = Descriptor(,)
    age = Descriptor(,)
    weight = Descriptor(,)

    (,name,age,weight):
        .name = name
        .age = age
        .weight = weight

lei  = Person(,,)

(%(lei.name,lei.age,lei.weight))



这样和我们一样调用实例化的结果一样了。

这就说明了数据描述符的优先级>实例属性>非数据描述符。



个人意见,望指正


更多资料文章请关注公众号:pythonislover ,回复 “python”