热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

描述符的应用

1、本来name应该是传字符串,age传数字,salary是传浮点数,但是我瞎传也可以,说明python没有帮我们判断这个类型classPeople:def__init

1、本来name应该是传字符串,age传数字,salary是传浮点数,但是我瞎传也可以,说明python没有帮我们判断这个类型

class People:
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
p1=People("gouguoqi",28,30000.0)
p2=People(222,"28",30000.0)

2、那我们用学过的描述符来判断一下类型

class Typed:#定义一个描述符Typed
    def __get__(self, instance, owner):#描述符必须要有get set delelte
        print("get方法")
        print("get instance参数[%s]" %instance)
        print("get ower参数[%s]"  %owner)
    def __set__(self, instance, value):
        print("set方法")
        print("set instance参数[%s]" % instance)
        print("set value参数[%s]" % value)
    def __delete__(self, instance):
        print("de instance参数[%s]" % instance)
class People:
    name=Typed()#描述符
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
p1=People("gouguoqi",28,30000.0)

C:\python35\python3.exe D:/pyproject/day30/描述符的应用.py

set方法

set instance参数[<__main__.People object at 0x00000000006D4588>]

set value参数[gouguoqi]

实例化的过程就是触发__init__然后赋值给name,就触发了__set__方法,

3、查看一下p1的属性字典,发现没有name。因为name被代理了,是一个Peopele的数据描述符

class Typed:#定义一个描述符Typed
    def __get__(self, instance, owner):#描述符必须要有get set delelte
        print("get方法")
        print("get instance参数[%s]" %instance)
        print("get ower参数[%s]"  %owner)
    def __set__(self, instance, value):
        print("set方法")
        print("set instance参数[%s]" % instance)
        print("set value参数[%s]" % value)
    def __delete__(self, instance):
        print("de instance参数[%s]" % instance)
class People:
    name=Typed()
    def __init__(self,name,age,salary):
        self.name=name#这里触发的是Typed的set方法
        self.age=age
        self.salary=salary
p1=People("gouguoqi",28,30000.0)

p1.name#调用实例p1的name属性,会触发描述符的get方法
print(p1.__dict__)

C:\python35\python3.exe D:/pyproject/day30/描述符的应用.py

set方法

set instance参数[<__main__.People object at 0x00000000006D4588>]

set value参数[gouguoqi]

get方法

get instance参数[<__main__.People object at 0x0000000000D44588>]

get ower参数[<class '__main__.People'>]

{'age': 28, 'salary': 30000.0}

4、实现真正意义的赋值和调用和删除,并存入实例的属性字典

class Typed:#定义一个描述符Typed
    def __init__(self,key):
        self.key=key
    def __get__(self, instance, owner):#描述符必须要有get set delelte
        print("get方法")
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print("set方法")
        instance.__dict__[self.key]=value

    def __delete__(self, instance):
        print("de instance参数[%s]" % instance)
        instance.__dict__.pop(self.key)
class People:
    name=Typed("name")
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
p1=People("gouguoqi",28,30000.0)
print(p1.__dict__)
print(p1.name)#调用实例p1的name属性,会触发描述符的get方法

C:\python35\python3.exe D:/pyproject/day30/描述符的应用.py

set方法

{'age': 28, 'name': 'gouguoqi', 'salary': 30000.0}

get方法

gouguoqi

5、试试修改一下名字的值

class Typed:#定义一个描述符Typed
    def __init__(self,key):
        self.key=key
    def __get__(self, instance, owner):#描述符必须要有get set delelte
        print("get方法")
        # print("get instance参数[%s]" %instance)
        # print("get ower参数[%s]"  %owner)
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print("set方法")
        # print("set instance参数[%s]" % instance)
        # print("set value参数[%s]" % value)
        instance.__dict__[self.key]=value

    def __delete__(self, instance):
        print("de instance参数[%s]" % instance)
        instance.__dict__.pop(self.key)
class People:
    name=Typed("name")
    # age = Typed("age")
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
p1=People("gouguoqi",28,30000.0)
print(p1.__dict__)#打印属性字典
p1.name="sb"#赋值给给实例的name属性的值,触发set
print(p1.name)#调用实例p1的name属性,会触发描述符的get方法

C:\python35\python3.exe D:/pyproject/day30/描述符的应用.py

set方法

{'name': 'gouguoqi', 'salary': 30000.0, 'age': 28}

set方法

get方法

sb

6、删除一下试试

class Typed:#定义一个描述符Typed
    def __init__(self,key):
        self.key=key
    def __get__(self, instance, owner):#描述符必须要有get set delelte
        print("get方法")
        # print("get instance参数[%s]" %instance)
        # print("get ower参数[%s]"  %owner)
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print("set方法")
        # print("set instance参数[%s]" % instance)
        # print("set value参数[%s]" % value)
        instance.__dict__[self.key]=value

    def __delete__(self, instance):
        # print("de instance参数[%s]" % instance)
        instance.__dict__.pop(self.key)
class People:
    name=Typed("name")
    # age = Typed("age")
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
p1=People("gouguoqi",28,30000.0)
print(p1.__dict__)#打印属性字典
del p1.name #删除实例的name属性 会触发Typed的delete方法
print(p1.__dict__)#再次查看属性字典

C:\python35\python3.exe D:/pyproject/day30/描述符的应用.py

set方法

{'name': 'gouguoqi', 'salary': 30000.0, 'age': 28}

{'salary': 30000.0, 'age': 28} 

7、加一个判断,如果name传入的值不是字符串的话就raise一个错误

(1)传入的是字符串的时候,一切正常

class Typed:#定义一个描述符Typed
    def __init__(self,key):
        self.key=key
    def __get__(self, instance, owner):#描述符必须要有get set delelte
        print("get方法")
        # print("get instance参数[%s]" %instance)
        # print("get ower参数[%s]"  %owner)
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print("set方法")
        # print("set instance参数[%s]" % instance)
        # print("set value参数[%s]" % value)
        if not isinstance(value,str):
            # print("你传入的不是字符串")
            # return
            raise TypeError("你传入的不是字符串")
        instance.__dict__[self.key]=value

    def __delete__(self, instance):
        # print("de instance参数[%s]" % instance)
        instance.__dict__.pop(self.key)
class People:
    name=Typed("name")
    # age = Typed("age")
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
p1=People("gouguoqi",28,30000.0)
print(p1.__dict__)#打印属性字典

C:\python35\python3.exe D:/pyproject/day30/描述符的应用.py

set方法

{'salary': 30000.0, 'name': 'gouguoqi', 'age': 28}

(2)传入的name不是字符串的时候

class Typed:#定义一个描述符Typed
    def __init__(self,key):
        self.key=key
    def __get__(self, instance, owner):#描述符必须要有get set delelte
        print("get方法")
        # print("get instance参数[%s]" %instance)
        # print("get ower参数[%s]"  %owner)
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print("set方法")
        # print("set instance参数[%s]" % instance)
        # print("set value参数[%s]" % value)
        if not isinstance(value,str):
            # print("你传入的不是字符串")
            # return
            raise TypeError("你传入的不是字符串")
        instance.__dict__[self.key]=value

    def __delete__(self, instance):
        # print("de instance参数[%s]" % instance)
        instance.__dict__.pop(self.key)
class People:
    name=Typed("name")
    # age = Typed("age")
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
p2=People(222,28,30000.0)

  File "D:/pyproject/day30/描述符的应用.py", line 22, in __set__

    raise TypeError("你传入的不是字符串")

TypeError: 你传入的不是字符串

8、我们现在实现了判断name的值是不是字符串,那么怎么来控制age必须是数字呢,现在的情况是我们age这里也必须得传入字符串才能正常运行

class Typed:#定义一个描述符Typed
    def __init__(self,key):
        self.key=key
    def __get__(self, instance, owner):#描述符必须要有get set delelte
        print("get方法")
        # print("get instance参数[%s]" %instance)
        # print("get ower参数[%s]"  %owner)
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print("set方法")
        if not isinstance(value,str):
            # print("你传入的不是字符串")
            # return
            raise TypeError("你传入的不是字符串")
        instance.__dict__[self.key]=value
    def __delete__(self, instance):
        # print("de instance参数[%s]" % instance)
        instance.__dict__.pop(self.key)
class People:
    name=Typed("name")
    age=Typed("age")
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
p2=People("gouguoqi","28",30000.0)
print(p2.age)

C:\python35\python3.exe D:/pyproject/day30/描述符的应用.py

set方法

set方法

get方法

28

那么应该怎么做呢,现在的问题就是,你判断的东西必须全部是字符串,是别的就会报错,这是写死了呀,那么如何写活呢

我们可以在复制一个Typed为Type1把判断条件改为int就行了

class Typed:#定义一个描述符Typed
    def __init__(self,key):
        self.key=key
    def __get__(self, instance, owner):#描述符必须要有get set delelte
        print("get方法")
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print("set方法")
        if not isinstance(value,str):
            raise TypeError("你传入的不是字符串")
        instance.__dict__[self.key]=value
    def __delete__(self, instance):
        instance.__dict__.pop(self.key)
class Typed1:#定义一个描述符Typed
    def __init__(self,key):
        self.key=key
    def __get__(self, instance, owner):#描述符必须要有get set delelte
        print("get方法")
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print("set方法")
        if not isinstance(value,int):
            raise TypeError("你传入的不是数字")
        instance.__dict__[self.key]=value
    def __delete__(self, instance):
        instance.__dict__.pop(self.key)
class People:
    name=Typed("name")
    age=Typed1("age")
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
p2=People("gouguoqi","28",30000.0)

TypeError: 你传入的不是数字

当我们age字段传入的参数是数字的时候就可以正常运行了,但是这样又是重复代码了呀

最终版本

class Typed:#定义一个描述符Typed
    def __init__(self,key,expec_type):
        self.key=key
        self.expec_type=expec_type
    def __get__(self, instance, owner):#描述符必须要有get set delelte
        print("get方法")
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        print("set方法")
        if not isinstance(value,self.expec_type):
            raise TypeError("%s你传入的不是%s" %(self.key,self.expec_type))
        instance.__dict__[self.key]=value
    def __delete__(self, instance):
        instance.__dict__.pop(self.key)
class People:
    name=Typed("name",str)
    age=Typed("age",int)
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.salary=salary
p2=People("gouguoqi","28",30000.0)

TypeError: age你传入的不是<class 'int'>

推荐阅读
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
author-avatar
手机用户2502862581
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有