当前位置: 首页 > news >正文

dw怎么做网站跳转今日足球赛事数据

dw怎么做网站跳转,今日足球赛事数据,手机端网站关键词排名,免费的网站或软件目录 一、描述符二、描述符的作用2.1 何时,何地,会触发这三个方法的执行三、两种描述符3.1 数据描述符3.2 非数据描述符四、描述符注意事项五、使用描述符5.1 牛刀小试5.2 拔刀相助5.3 磨刀霍霍5.4 大刀阔斧5.4.1 类的装饰器:无参5.4.2 类的装饰器:有参5…

目录

  • 一、描述符
  • 二、描述符的作用
    • 2.1 何时,何地,会触发这三个方法的执行
  • 三、两种描述符
    • 3.1 数据描述符
    • 3.2 非数据描述符
  • 四、描述符注意事项
  • 五、使用描述符
    • 5.1 牛刀小试
    • 5.2 拔刀相助
    • 5.3 磨刀霍霍
    • 5.4 大刀阔斧
      • 5.4.1 类的装饰器:无参
      • 5.4.2 类的装饰器:有参
    • 5.5 刀光剑影
  • 六、描述符总结
  • 七、自定制@property
    • 7.1 property回顾
    • 7.2 自定制property
    • 7.3 实现延迟计算功能
  • 八、打破延迟计算
  • 九、自定制@classmethod
  • 一十、自定制@staticmethod

103-描述符(get,set,delete)-预警.gif

一、描述符

  • 描述符是什么:描述符本质就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,这也被称为描述符协议

    • __get__():调用一个属性时,触发

    • __set__():为一个属性赋值时,触发

    • __delete__():采用del删除属性时,触发

  • 定义一个描述符

class Foo:  # 在python3中Foo是新式类,它实现了__get__(),__set__(),__delete__()中的一个三种方法的一个,这个类就被称作一个描述符def __get__(self, instance, owner):passdef __set__(self, instance, value):passdef __delete__(self, instance):pass

二、描述符的作用

  • 描述符是干什么的:描述符的作用是用来代理另外一个类的属性的,必须把描述符定义成这个类的类属性,不能定义到构造函数中
class Foo:def __get__(self, instance, owner):print('触发get')def __set__(self, instance, value):print('触发set')def __delete__(self, instance):print('触发delete')f1 = Foo()
  • 包含这三个方法的新式类称为描述符,由这个类产生的实例进行属性的调用/赋值/删除,并不会触发这三个方法
f1.name = 'nick'
f1.name
del f1.name

2.1 何时,何地,会触发这三个方法的执行

class Str:"""描述符Str"""def __get__(self, instance, owner):print('Str调用')def __set__(self, instance, value):print('Str设置...')def __delete__(self, instance):print('Str删除...')class Int:"""描述符Int"""def __get__(self, instance, owner):print('Int调用')def __set__(self, instance, value):print('Int设置...')def __delete__(self, instance):print('Int删除...')class People:name = Str()age = Int()def __init__(self, name, age):  # name被Str类代理,age被Int类代理self.name = nameself.age = age# 何地?:定义成另外一个类的类属性# 何时?:且看下列演示p1 = People('alex', 18)
Str设置...
Int设置...
  • 描述符Str的使用
p1.name
p1.name = 'nick'
del p1.name
Str调用
Str设置...
Str删除...
  • 描述符Int的使用
p1.age
p1.age = 18
del p1.age
Int调用
Int设置...
Int删除...
  • 我们来瞅瞅到底发生了什么
print(p1.__dict__)
print(People.__dict__)
{}
{'__module__': '__main__', 'name': <__main__.Str object at 0x107a86940>, 'age': <__main__.Int object at 0x107a863c8>, '__init__': <function People.__init__ at 0x107ba2ae8>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None}
  • 补充
print(type(p1) == People)  # type(obj)其实是查看obj是由哪个类实例化来的
print(type(p1).__dict__ == People.__dict__)
True
True

三、两种描述符

3.1 数据描述符

  • 至少实现了__get__()和__set__()
class Foo:def __set__(self, instance, value):print('set')def __get__(self, instance, owner):print('get')

3.2 非数据描述符

  • 没有实现__set__()
class Foo:def __get__(self, instance, owner):print('get')

四、描述符注意事项

103-描述符(get,set,delete)-注意.jpg?x-oss-process=style/watermark

  1. 描述符本身应该定义成新式类,被代理的类也应该是新式类

  2. 必须把描述符定义成这个类的类属性,不能为定义到构造函数中

  3. 要严格遵循该优先级,优先级由高到底分别是

    1.类属性

    2.数据描述符

    3.实例属性

    4.非数据描述符

    5.找不到的属性触发__getattr__()

五、使用描述符

  • 众所周知,python是弱类型语言,即参数的赋值没有类型限制,下面我们通过描述符机制来实现类型限制功能

5.1 牛刀小试

class Str:def __init__(self, name):self.name = namedef __get__(self, instance, owner):print('get--->', instance, owner)return instance.__dict__[self.name]def __set__(self, instance, value):print('set--->', instance, value)instance.__dict__[self.name] = valuedef __delete__(self, instance):print('delete--->', instance)instance.__dict__.pop(self.name)class People:name = Str('name')def __init__(self, name, age, salary):self.name = nameself.age = ageself.salary = salaryp1 = People('nick', 18, 3231.3)
set---> <__main__.People object at 0x107a86198> nick
  • 调用
print(p1.__dict__)
{'name': 'nick', 'age': 18, 'salary': 3231.3}
print(p1.name)
get---> <__main__.People object at 0x107a86198> <class '__main__.People'>
nick
  • 赋值
print(p1.__dict__)
{'name': 'nick', 'age': 18, 'salary': 3231.3}
p1.name = 'nicklin'
print(p1.__dict__)
set---> <__main__.People object at 0x107a86198> nicklin
{'name': 'nicklin', 'age': 18, 'salary': 3231.3}
  • 删除
print(p1.__dict__)
{'name': 'nicklin', 'age': 18, 'salary': 3231.3}
del p1.name
print(p1.__dict__)
delete---> <__main__.People object at 0x107a86198>
{'age': 18, 'salary': 3231.3}

5.2 拔刀相助

class Str:def __init__(self, name):self.name = namedef __get__(self, instance, owner):print('get--->', instance, owner)return instance.__dict__[self.name]def __set__(self, instance, value):print('set--->', instance, value)instance.__dict__[self.name] = valuedef __delete__(self, instance):print('delete--->', instance)instance.__dict__.pop(self.name)class People:name = Str('name')def __init__(self, name, age, salary):self.name = nameself.age = ageself.salary = salary# 疑问:如果我用类名去操作属性呢
try:People.name  # 报错,错误的根源在于类去操作属性时,会把None传给instance
except Exception as e:print(e)
get---> None <class '__main__.People'>
'NoneType' object has no attribute '__dict__'
  • 修订__get__方法
class Str:def __init__(self, name):self.name = namedef __get__(self, instance, owner):print('get--->', instance, owner)if instance is None:return selfreturn instance.__dict__[self.name]def __set__(self, instance, value):print('set--->', instance, value)instance.__dict__[self.name] = valuedef __delete__(self, instance):print('delete--->', instance)instance.__dict__.pop(self.name)class People:name = Str('name')def __init__(self, name, age, salary):self.name = nameself.age = ageself.salary = salaryprint(People.name)  # 完美,解决
get---> None <class '__main__.People'>
<__main__.Str object at 0x107a86da0>

5.3 磨刀霍霍

class Str:def __init__(self, name, expected_type):self.name = nameself.expected_type = expected_typedef __get__(self, instance, owner):print('get--->', instance, owner)if instance is None:return selfreturn instance.__dict__[self.name]def __set__(self, instance, value):print('set--->', instance, value)if not isinstance(value, self.expected_type):  # 如果不是期望的类型,则抛出异常raise TypeError('Expected %s' % str(self.expected_type))instance.__dict__[self.name] = valuedef __delete__(self, instance):print('delete--->', instance)instance.__dict__.pop(self.name)class People:name = Str('name', str)  # 新增类型限制strdef __init__(self, name, age, salary):self.name = nameself.age = ageself.salary = salarytry:p1 = People(123, 18, 3333.3)  # 传入的name因不是字符串类型而抛出异常
except Exception as e:print(e)
set---> <__main__.People object at 0x1084cd940> 123
Expected <class 'str'>

5.4 大刀阔斧

class Typed:def __init__(self, name, expected_type):self.name = nameself.expected_type = expected_typedef __get__(self, instance, owner):print('get--->', instance, owner)if instance is None:return selfreturn instance.__dict__[self.name]def __set__(self, instance, value):print('set--->', instance, value)if not isinstance(value, self.expected_type):raise TypeError('Expected %s' % str(self.expected_type))instance.__dict__[self.name] = valuedef __delete__(self, instance):print('delete--->', instance)instance.__dict__.pop(self.name)class People:name = Typed('name', str)age = Typed('name', int)salary = Typed('name', float)def __init__(self, name, age, salary):self.name = nameself.age = ageself.salary = salarytry:p1 = People(123, 18, 3333.3)
except Exception as e:print(e)
set---> <__main__.People object at 0x1082c7908> 123
Expected <class 'str'>
try:p1 = People('nick', '18', 3333.3)
except Exception as e:print(e)
set---> <__main__.People object at 0x1078dd438> nick
set---> <__main__.People object at 0x1078dd438> 18
Expected <class 'int'>
p1 = People('nick', 18, 3333.3)
set---> <__main__.People object at 0x1081b3da0> nick
set---> <__main__.People object at 0x1081b3da0> 18
set---> <__main__.People object at 0x1081b3da0> 3333.3
  • 大刀阔斧之后我们已然能实现功能了,但是问题是,如果我们的类有很多属性,你仍然采用在定义一堆类属性的方式去实现,low,这时候我需要教你一招:独孤九剑

103-描述符(get,set,delete)-独孤九剑.jpg?x-oss-process=style/watermark

5.4.1 类的装饰器:无参

def decorate(cls):print('类的装饰器开始运行啦------>')return cls@decorate  # 无参:People = decorate(People)
class People:def __init__(self, name, age, salary):self.name = nameself.age = ageself.salary = salaryp1 = People('nick', 18, 3333.3)
类的装饰器开始运行啦------>

5.4.2 类的装饰器:有参

def typeassert(**kwargs):def decorate(cls):print('类的装饰器开始运行啦------>', kwargs)return clsreturn decorate@typeassert(name=str, age=int, salary=float
)  # 有参:1.运行typeassert(...)返回结果是decorate,此时参数都传给kwargs 2.People=decorate(People)
class People:def __init__(self, name, age, salary):self.name = nameself.age = ageself.salary = salaryp1 = People('nick', 18, 3333.3)
类的装饰器开始运行啦------> {'name': <class 'str'>, 'age': <class 'int'>, 'salary': <class 'float'>}

5.5 刀光剑影

class Typed:def __init__(self, name, expected_type):self.name = nameself.expected_type = expected_typedef __get__(self, instance, owner):print('get--->', instance, owner)if instance is None:return selfreturn instance.__dict__[self.name]def __set__(self, instance, value):print('set--->', instance, value)if not isinstance(value, self.expected_type):raise TypeError('Expected %s' % str(self.expected_type))instance.__dict__[self.name] = valuedef __delete__(self, instance):print('delete--->', instance)instance.__dict__.pop(self.name)def typeassert(**kwargs):def decorate(cls):print('类的装饰器开始运行啦------>', kwargs)for name, expected_type in kwargs.items():setattr(cls, name, Typed(name, expected_type))return clsreturn decorate@typeassert(name=str, age=int, salary=float
)  # 有参:1.运行typeassert(...)返回结果是decorate,此时参数都传给kwargs 2.People=decorate(People)
class People:def __init__(self, name, age, salary):self.name = nameself.age = ageself.salary = salaryprint(People.__dict__)
p1 = People('nick', 18, 3333.3)
类的装饰器开始运行啦------> {'name': <class 'str'>, 'age': <class 'int'>, 'salary': <class 'float'>}
{'__module__': '__main__', '__init__': <function People.__init__ at 0x10797a400>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None, 'name': <__main__.Typed object at 0x1080b2a58>, 'age': <__main__.Typed object at 0x1080b2ef0>, 'salary': <__main__.Typed object at 0x1080b2c18>}
set---> <__main__.People object at 0x1080b22e8> nick
set---> <__main__.People object at 0x1080b22e8> 18
set---> <__main__.People object at 0x1080b22e8> 3333.3

六、描述符总结

  • 描述符是可以实现大部分python类特性中的底层魔法,包括@classmethod,@staticmethd,@property甚至是__slots__属性

  • 描述父是很多高级库和框架的重要工具之一,描述符通常是使用到装饰器或者元类的大型框架中的一个组件.

103-描述符(get,set,delete)-私人订制.jpg?x-oss-process=style/watermark

七、自定制@property

  • 利用描述符原理完成一个自定制@property,实现延迟计算(本质就是把一个函数属性利用装饰器原理做成一个描述符:类的属性字典中函数名为key,value为描述符类产生的对象)

7.1 property回顾

class Room:def __init__(self, name, width, length):self.name = nameself.width = widthself.length = length@propertydef area(self):return self.width * self.lengthr1 = Room('alex', 1, 1)
print(r1.area)
1

7.2 自定制property

class Lazyproperty:def __init__(self, func):self.func = funcdef __get__(self, instance, owner):print('这是我们自己定制的静态属性,r1.area实际是要执行r1.area()')if instance is None:return selfreturn self.func(instance)  # 此时你应该明白,到底是谁在为你做自动传递self的事情class Room:def __init__(self, name, width, length):self.name = nameself.width = widthself.length = length@Lazyproperty  # area=Lazyproperty(area) 相当于定义了一个类属性,即描述符def area(self):return self.width * self.lengthr1 = Room('alex', 1, 1)
print(r1.area)
这是我们自己定制的静态属性,r1.area实际是要执行r1.area()
1

7.3 实现延迟计算功能

class Lazyproperty:def __init__(self, func):self.func = funcdef __get__(self, instance, owner):print('这是我们自己定制的静态属性,r1.area实际是要执行r1.area()')if instance is None:return selfelse:print('--->')value = self.func(instance)setattr(instance, self.func.__name__, value)  # 计算一次就缓存到实例的属性字典中return valueclass Room:def __init__(self, name, width, length):self.name = nameself.width = widthself.length = length@Lazyproperty  # area=Lazyproperty(area) 相当于'定义了一个类属性,即描述符'def area(self):return self.width * self.lengthr1 = Room('alex', 1, 1)
print(r1.area)  # 先从自己的属性字典找,没有再去类的中找,然后出发了area的__get__方法
这是我们自己定制的静态属性,r1.area实际是要执行r1.area()
--->
1
print(r1.area)  # 先从自己的属性字典找,找到了,是上次计算的结果,这样就不用每执行一次都去计算
1

八、打破延迟计算

  • 一个小的改动,延迟计算的美梦就破碎了
class Lazyproperty:def __init__(self, func):self.func = funcdef __get__(self, instance, owner):print('这是我们自己定制的静态属性,r1.area实际是要执行r1.area()')if instance is None:return selfelse:value = self.func(instance)instance.__dict__[self.func.__name__] = valuereturn value# return self.func(instance) # 此时你应该明白,到底是谁在为你做自动传递self的事情def __set__(self, instance, value):print('hahahahahah')class Room:def __init__(self, name, width, length):self.name = nameself.width = widthself.length = length@Lazyproperty  # area=Lazyproperty(area) 相当于定义了一个类属性,即描述符def area(self):return self.width * self.length
print(Room.__dict__)
{'__module__': '__main__', '__init__': <function Room.__init__ at 0x107d53620>, 'area': <__main__.Lazyproperty object at 0x107ba3860>, '__dict__': <attribute '__dict__' of 'Room' objects>, '__weakref__': <attribute '__weakref__' of 'Room' objects>, '__doc__': None}
r1 = Room('alex', 1, 1)
print(r1.area)
print(r1.area)
print(r1.area)
这是我们自己定制的静态属性,r1.area实际是要执行r1.area()
1
这是我们自己定制的静态属性,r1.area实际是要执行r1.area()
1
这是我们自己定制的静态属性,r1.area实际是要执行r1.area()
1
print(r1.area
)  #缓存功能失效,每次都去找描述符了,为何,因为描述符实现了set方法,它由非数据描述符变成了数据描述符,数据描述符比实例属性有更高的优先级,因而所有的属性操作都去找描述符了
这是我们自己定制的静态属性,r1.area实际是要执行r1.area()
1

九、自定制@classmethod

class ClassMethod:def __init__(self, func):self.func = funcdef __get__(self, instance,owner):  #类来调用,instance为None,owner为类本身,实例来调用,instance为实例,owner为类本身,def feedback():print('在这里可以加功能啊...')return self.func(owner)return feedbackclass People:name = 'nick'@ClassMethod  # say_hi=ClassMethod(say_hi)def say_hi(cls):print('你好啊,帅哥 %s' % cls.name)People.say_hi()p1 = People()
在这里可以加功能啊...
你好啊,帅哥 nick
p1.say_hi()
在这里可以加功能啊...
你好啊,帅哥 nick
  • 疑问,类方法如果有参数呢,好说,好说
class ClassMethod:def __init__(self, func):self.func = funcdef __get__(self, instance, owner):  # 类来调用,instance为None,owner为类本身,实例来调用,instance为实例,owner为类本身,def feedback(*args, **kwargs):print('在这里可以加功能啊...')return self.func(owner, *args, **kwargs)return feedbackclass People:name = 'nick'@ClassMethod  # say_hi=ClassMethod(say_hi)def say_hi(cls, msg):print('你好啊,帅哥 %s %s' % (cls.name, msg))People.say_hi('你是那偷心的贼')p1 = People()
在这里可以加功能啊...
你好啊,帅哥 nick 你是那偷心的贼
p1.say_hi('你是那偷心的贼')
在这里可以加功能啊...
你好啊,帅哥 nick 你是那偷心的贼

一十、自定制@staticmethod

class StaticMethod:def __init__(self, func):self.func = funcdef __get__(self, instance,owner):  # 类来调用,instance为None,owner为类本身,实例来调用,instance为实例,owner为类本身def feedback(*args, **kwargs):print('在这里可以加功能啊...')return self.func(*args, **kwargs)return feedbackclass People:@StaticMethod  # say_hi = StaticMethod(say_hi)def say_hi(x, y, z):print('------>', x, y, z)People.say_hi(1, 2, 3)p1 = People()
在这里可以加功能啊...
------> 1 2 3
p1.say_hi(4, 5, 6)
在这里可以加功能啊...
------> 4 5 6

103-描述符(get,set,delete)-放假.jpg?x-oss-process=style/watermark

转载于:https://www.cnblogs.com/nickchen121/p/10991295.html

http://www.lbrq.cn/news/2456875.html

相关文章:

  • 云南网站优化排名网络软文营销
  • 如何添加网站白名单今日新闻最新头条10条摘抄
  • 在手机上做网站是什么软件同城推广引流平台
  • 大学生做外包项目的网站seo排名软件免费
  • 摄影培训网站建设百度推广电话是多少
  • 第一个做装修的网站网络营销有哪些就业岗位
  • 美食网站怎么做美国seo薪酬
  • 十堰seo优化服务长沙关键词优化推荐
  • 湖南网站制作公司乐天seo视频教程
  • j2ee做网站2023年国家免费技能培训
  • 唐卡装饰集团 一站式超级体验店西安关键词优化软件
  • 东川网站制作怎样在百度上发表文章
  • 品牌策划网站建设旺道seo网站优化大师
  • 织梦网站地图生成网络推广员工作内容
  • 网页视频加速器优化软件
  • 网站建设费用报价单淘宝seo搜索引擎优化
  • 广州高端模板网站查询网站流量
  • 威客网站开发需求国外网站seo免费
  • 阿里云网站备案核验单舆情报告范文
  • 网站建设工具品牌有合肥网络推广平台
  • 红酒公司网站建设模板6841百度高级搜索首页
  • 做网站还能挣钱吗网络销售平台上市公司有哪些
  • 崇信县门户网站首页欧洲网站服务器
  • 麻将网站开发公司品牌策划公司排行榜
  • 17网站一起做网店 睡衣百度seo排名培训
  • 公司网站建设优帮云企业培训员工培训平台
  • 九江网站建设排行榜网络运营推广具体做什么工作
  • 静态网站怎么做优化深圳网络营销平台
  • 外贸网站建设制作google下载手机版
  • 廊坊那家做网站排行榜seo文章优化方法
  • 大模型Prompt优化工程
  • 智慧工厂网络升级:新型 SD-WAN 技术架构与应用解析
  • List和Map的区别
  • VirtualBox安装提示security安全问题
  • pluto example, heat-1d优化分析
  • 《使用Qt Quick从零构建AI螺丝瑕疵检测系统》——1. 启航:你的第一个工业视觉应用