#!/usr/bin/env python
# -*- coding:utf-8 -*-
# ------------------------------------------------------------
#
# 参考资料:
# 面向对象进阶 - linhaifeng - 博客园
# https://www.cnblogs.com/linhaifeng/articles/6204014.html#_label12
#
# python之函数介绍及使用 - 病毒尖er - 博客园
# http://www.cnblogs.com/leguan1314/articles/6116928.html
#
# 元类metaclass - linhaifeng - 博客园
# http://www.cnblogs.com/linhaifeng/articles/8029564.html
#
# ------------------------------------------------------------
# ******************** day28-描述符应用与类的装饰器 *******************
# ******************** day28-描述符应用与类的装饰器 *******************
# =====>>>>>>内容概览
# =====>>>>>>内容概览
# Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi

'''
# ------------------------------------------------------------
# # 1、总结:
# # # hasattr, getattr, setattr;;  getitem, setitem, delitem;; set, get, delete;; __del__
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 2、 __enter__ 与 __exit__
# # # 这个使用的方法是类似于 with open() as 文件名;    
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 3、 __enter__ 与 __exit__ 之文件异常引入
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# # # 这个使用的方法是类似于 with open() as 文件名;    
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 3.1、 __enter__ 与 __exit__ 之文件异常引入1
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# # # 这个使用的方法是类似于 with open() as 文件名;    
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 3.2、 __exit__ 中 exc_type, exc_val, exc_tb 之文件异常引入1
# # # __exit__ 中的 exc_type, exc_val, exc_tb 就是文件异常的信息内容
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 3.3、 __exit__ 中 exc_type, exc_val, exc_tb 之文件异常
# # # __exit__ 中的 exc_type, exc_val, exc_tb 就是文件异常的信息内容
# # # __exit__ 中的返回值设置为True时,文件的异常会结束该文件内容的操作,但是对于
# # # 该操作外的操作信息不会有所影响,仍能够正常运行 
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 3.4、总结 __enter__ 与 __exit__ 
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 4、描述符的应用的引入
# # # test给定的参数中,如果是字符串或者整形数字就输出,否则留报错!显然,
# # # 下面的例子中,是不能够满足该要求的;  下面关于描述符的应用就是为了解决该问题
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 5、描述符中 __set__ 中的各个参数
# # # __set__中的各个参数:
# # # instance : 修饰的实例本身(下例中,就是实例p1)
# # # value    :实例中修饰的那个值(下例中,就是 alex)
# # # self     :描述符所在的类本身
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 6、描述符中 __get__ 中的各个参数
# # # __get__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# # # owner    :修饰的实例所属的类(下例中,是类People)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 6.1、描述符中 __get__ 中的各个参数
# # # __get__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# # # owner    :修饰的实例所属的类(下例中,是类People)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 6.2、描述符中 __delete__ 中的各个参数
# # # __delete__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 7、__set__  使用描述符给给定的实例中传入值  
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 8、__set__  使用描述符对给定的实例 获取对应的值  
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 9、使用描述符对给定的实例 的值的设定进行限制1
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 9.1、使用描述符对给定的实例 的值的设定进行限制2
# # # 对类进行修饰的时候,直接指定数值属性的  类型 ,如name 是str类型
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 10、装饰器的引入,修饰函数
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 11、装饰器修饰 类
# # # 类中的装饰器的运行的情况,是跟上面的函数的装饰器是有所区别的; 类中的是下运行类,之后再运行装饰器的运行
# # # 而函数中的,是先运行装饰器中的内容,之后再运行函数的内容
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 12、函数也是有字典的
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 12.1、给函数的字典添加属性
# # # 函数也可以像类一像添加属性,因为函数的本质就是类;python中的一切都是对像
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 13、使用装饰器给类中的字典添加属性
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 14、使用装饰器给类中的字典添加属性
# # # 只能在装饰器中内部给定值的情况
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 14.1、使用装饰器给类中的字典添加属性1
# # # 解决只能在装饰器中内部给定值的情况
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 15、装饰器的应用(与前面的序号10对比)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 16、property 的使用
# # # property() 函数的作用是在新式类中返回属性值。
# # # 下面例子中,(原)r1.area()-->>(现)r1.area 
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 17、property引入 , 类的装饰器
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 18、property装饰器初步 , 类的装饰器
# # # print(r1.area.func(r1))   实现了基本的装饰器功能
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 18.1、property装饰器初步之 __get__ , 类的装饰器
# # # 目标: print(r1.area.func(r1)) ==>> 等价于执行   print(r1.area) 
# # # __get__ 接受被修饰对象中的实例, 
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 18.2、property装饰器“实现”之 __get__ 返回运行的内容, 类的装饰器
# # # 目标(实现): print(r1.area.func(r1)) ==>> 等价于执行   print(r1.area) 
# # # __get__ 接受被修饰对象中的实例, 
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 18.3、property装饰器“实现” (简洁版)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 18.4、property装饰器“实现” (简洁版) 与 内置的property装饰器对比1
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 19、property装饰器,之类调用静态属性 对比
# # # “实现” (简洁版) 与 内置的property装饰器
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 19.1、property装饰器,之类调用静态属性,实现property的完整功能( 类无法调用静态属性)
# # # “实现” (简洁版) 与 内置的property装饰器
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 20、__name__获取函数的名字
# # # 用来获取运行的模块的名字,  或者对应的对象的名字(类是获取不到名字的)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 21、property装饰器,之类调用静态属性,实现property的完整功能
# # # “实现” (简洁版) 与 内置的property装饰器
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 21.1、元类的引入
# # # python中一切皆为对象。类的本身也是一个对象,由 type 产生
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 22、type 元类来产生 类

# # # FFo = type("FFo", (object,), {'x': 1})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo",      类名
# # # 位置2:(object,),  对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3:{'x': 1},    类的属性字典
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 22.1、type 元类来产生 类
# # # 给类中添加类的初始化属数,类的数值属性, 类的函数属性

# # # FFo = type("FFo", (object,), {'x':1, '__init__':__init__, 'test':test})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo",      类名
# # # 位置2:(object,),  对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3: {'x':1, '__init__':__init__, 'test':test},    类的属性字典
# # # 'x':1  相当于在类中定义数值属性   x = 1
# # # '__init__':__init__  相当于在类中定义类初化始的函数属性   def __init__(self)
# # # 'test':test          相当于在类中定义类的函数属性   def test(self)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 22.2、type 元类产生的类进行  实例化
# # # 给类中添加类的初始化属数,类的数值属性, 类的函数属性

# # # FFo = type("FFo", (object,), {'x':1, '__init__':__init__, 'test':test})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo",      类名
# # # 位置2:(object,),  对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3: {'x':1, '__init__':__init__, 'test':test},    类的属性字典
# # # 'x':1  相当于在类中定义数值属性   x = 1
# # # '__init__':__init__  相当于在类中定义类初化始的函数属性   def __init__(self)
# # # 'test':test          相当于在类中定义类的函数属性   def test(self)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 22.3、类的产生总结
# # # 类的产生有两种方式,1、通过 class来定义类;       2、通过type来产生类
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 23、自定义元类引入,元类定义自己的元类type
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 24、自定义元类引入,__call__ 方法介绍
# # # 实例运加括号的时候,即实例 f1() 时候,会触发所属的类中的 __call__方法
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 24.1、自定义元类引入,__call__ 方法介绍
# # # 实例运加括号的时候,即实例 f1() 时候,会触发所属的类中的 __call__方法
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 25.1、自定义元类引入1,元类定义自己的元类type
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 25.2、自定义元类引入2,元类定义自己的元类type
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 25.3、自定义元类引入2( 实例传入的内容信息),自定义元类中的 __call__ 方法
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs):
# # # __call__ 接收着,我们使用 Foo类 进行实例化时候的信息
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 25.3、自定义元类实现,自定义元类中的 __call__ 方法
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs):

# ------------------------------------------------------------

# ------------------------------------------------------------
# # 25.4、自定义元类实现(简洁版)
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs):
# ------------------------------------------------------------

'''

# ------------------------------------------------分割线-------------------------------------------------
# ------------------------------------------------分割线-------------------------------------------------
# ------------------------------------------------分割线-------------------------------------------------
# ------------------------------------------------------------
# # 1、总结:
# # # hasattr, getattr, setattr;; getitem, setitem, delitem;; set, get, delete;; __del__
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 2、 __enter__ 与 __exit__
# # # 这个使用的方法是类似于 with open() as 文件名;
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 3、 __enter__ 与 __exit__ 之文件异常引入
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# # # 这个使用的方法是类似于 with open() as 文件名;
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 3.1、 __enter__ 与 __exit__ 之文件异常引入1
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# # # 这个使用的方法是类似于 with open() as 文件名;
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 3.2、 __exit__ 中 exc_type, exc_val, exc_tb 之文件异常引入1
# # # __exit__ 中的 exc_type, exc_val, exc_tb 就是文件异常的信息内容
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 3.3、 __exit__ 中 exc_type, exc_val, exc_tb 之文件异常
# # # __exit__ 中的 exc_type, exc_val, exc_tb 就是文件异常的信息内容
# # # __exit__ 中的返回值设置为True时,文件的异常会结束该文件内容的操作,但是对于
# # # 该操作外的操作信息不会有所影响,仍能够正常运行
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 3.4、总结 __enter__ 与 __exit__
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 4、描述符的应用的引入
# # # test给定的参数中,如果是字符串或者整形数字就输出,否则留报错!显然,
# # # 下面的例子中,是不能够满足该要求的; 下面关于描述符的应用就是为了解决该问题
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 5、描述符中 __set__ 中的各个参数
# # # __set__中的各个参数:
# # # instance : 修饰的实例本身(下例中,就是实例p1)
# # # value :实例中修饰的那个值(下例中,就是 alex)
# # # self :描述符所在的类本身
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 6、描述符中 __get__ 中的各个参数
# # # __get__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# # # owner :修饰的实例所属的类(下例中,是类People)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 6.1、描述符中 __get__ 中的各个参数
# # # __get__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# # # owner :修饰的实例所属的类(下例中,是类People)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 6.2、描述符中 __delete__ 中的各个参数
# # # __delete__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 7、__set__ 使用描述符给给定的实例中传入值
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 8、__set__ 使用描述符对给定的实例 获取对应的值
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 9、使用描述符对给定的实例 的值的设定进行限制1
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 9.1、使用描述符对给定的实例 的值的设定进行限制2
# # # 对类进行修饰的时候,直接指定数值属性的 类型 ,如name 是str类型
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 10、装饰器的引入,修饰函数
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 11、装饰器修饰 类
# # # 类中的装饰器的运行的情况,是跟上面的函数的装饰器是有所区别的; 类中的是下运行类,之后再运行装饰器的运行
# # # 而函数中的,是先运行装饰器中的内容,之后再运行函数的内容
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 12、函数也是有字典的
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 12.1、给函数的字典添加属性
# # # 函数也可以像类一像添加属性,因为函数的本质就是类;python中的一切都是对像
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 13、使用装饰器给类中的字典添加属性
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 14、使用装饰器给类中的字典添加属性
# # # 只能在装饰器中内部给定值的情况
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 14.1、使用装饰器给类中的字典添加属性1
# # # 解决只能在装饰器中内部给定值的情况
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 15、装饰器的应用(与前面的序号10对比)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 16、property 的使用
# # # property() 函数的作用是在新式类中返回属性值。
# # # 下面例子中,(原)r1.area()-->>(现)r1.area
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 17、property引入 , 类的装饰器
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 18、property装饰器初步 , 类的装饰器
# # # print(r1.area.func(r1)) 实现了基本的装饰器功能
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 18.1、property装饰器初步之 __get__ , 类的装饰器
# # # 目标: print(r1.area.func(r1)) ==>> 等价于执行 print(r1.area)
# # # __get__ 接受被修饰对象中的实例,
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 18.2、property装饰器“实现”之 __get__ 返回运行的内容, 类的装饰器
# # # 目标(实现): print(r1.area.func(r1)) ==>> 等价于执行 print(r1.area)
# # # __get__ 接受被修饰对象中的实例,
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 18.3、property装饰器“实现” (简洁版)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 18.4、property装饰器“实现” (简洁版) 与 内置的property装饰器对比1
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 19、property装饰器,之类调用静态属性 对比
# # # “实现” (简洁版) 与 内置的property装饰器
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 19.1、property装饰器,之类调用静态属性,实现property的完整功能( 类无法调用静态属性)
# # # “实现” (简洁版) 与 内置的property装饰器
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 20、__name__获取函数的名字
# # # 用来获取运行的模块的名字, 或者对应的对象的名字(类是获取不到名字的)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 21、property装饰器,之类调用静态属性,实现property的完整功能
# # # “实现” (简洁版) 与 内置的property装饰器
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 21.1、元类的引入
# # # python中一切皆为对象。类的本身也是一个对象,由 type 产生
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 22、type 元类来产生 类 # # # FFo = type("FFo", (object,), {'x': 1})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo", 类名
# # # 位置2:(object,), 对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3:{'x': 1}, 类的属性字典
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 22.1、type 元类来产生 类
# # # 给类中添加类的初始化属数,类的数值属性, 类的函数属性 # # # FFo = type("FFo", (object,), {'x':1, '__init__':__init__, 'test':test})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo", 类名
# # # 位置2:(object,), 对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3: {'x':1, '__init__':__init__, 'test':test}, 类的属性字典
# # # 'x':1 相当于在类中定义数值属性 x = 1
# # # '__init__':__init__ 相当于在类中定义类初化始的函数属性 def __init__(self)
# # # 'test':test 相当于在类中定义类的函数属性 def test(self)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 22.2、type 元类产生的类进行 实例化
# # # 给类中添加类的初始化属数,类的数值属性, 类的函数属性 # # # FFo = type("FFo", (object,), {'x':1, '__init__':__init__, 'test':test})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo", 类名
# # # 位置2:(object,), 对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3: {'x':1, '__init__':__init__, 'test':test}, 类的属性字典
# # # 'x':1 相当于在类中定义数值属性 x = 1
# # # '__init__':__init__ 相当于在类中定义类初化始的函数属性 def __init__(self)
# # # 'test':test 相当于在类中定义类的函数属性 def test(self)
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 22.3、类的产生总结
# # # 类的产生有两种方式,1、通过 class来定义类; 2、通过type来产生类
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 23、自定义元类引入,元类定义自己的元类type
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 24、自定义元类引入,__call__ 方法介绍
# # # 实例运加括号的时候,即实例 f1() 时候,会触发所属的类中的 __call__方法
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 24.1、自定义元类引入,__call__ 方法介绍
# # # 实例运加括号的时候,即实例 f1() 时候,会触发所属的类中的 __call__方法
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 25.1、自定义元类引入1,元类定义自己的元类type
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 25.2、自定义元类引入2,元类定义自己的元类type
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 25.3、自定义元类引入2( 实例传入的内容信息),自定义元类中的 __call__ 方法
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs):
# # # __call__ 接收着,我们使用 Foo类 进行实例化时候的信息
# ------------------------------------------------------------ # ------------------------------------------------------------
# # 25.3、自定义元类实现,自定义元类中的 __call__ 方法
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs): # ------------------------------------------------------------ # ------------------------------------------------------------
# # 25.4、自定义元类实现(简洁版)
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs):
# ------------------------------------------------------------ ''' # ------------------------------------------------分割线-------------------------------------------------
# ------------------------------------------------分割线-------------------------------------------------
# ------------------------------------------------分割线-------------------------------------------------
# '''
# ------------------------------------------------------------
# # 1、总结:
# # # hasattr, getattr, setattr;; getitem, setitem, delitem;; set, get, delete;; __del__
# ------------------------------------------------------------
''' '''
#自省
hasattr(obj,'属性') #obj.属性 是否存在
getattr(obj,'属性') #获取obj.属性 不存在则报错
getattr(obj,'属性','默认值') #获取obj.属性 不存在不会报错,返回那个默认值
setattr(obj,'属性','属性的值') #obj.属性=属性的值
delattr(obj,'属性') #del obj.属性 #__getattr__,__setattr__,__delattr__
obj点的方式去操作属性时触发的方法 __getattr__:obj.属性 不存在时触发
__setattr__:obj.属性=属性的值 时触发
__delattr__:del obj.属性 时触发 #__getitem__,__setitem_,__delitem__
obj[‘属性’]的方式去操作属性时触发的方法 __getitem__:obj['属性'] 时触发
__setitem__:obj['属性']=属性的值 时触发
__delitem__:del obj['属性'] 时触发 #__get__,__set__,__delete__
描述就是一个新式类,这个类至少要实现上述三个方法的一个
class 描述符:
def __get__():
pass
def __set__():
pass
def __delete__():
pass class 类:
name=描述符() obj=类()
obj.name #get
obj.name='egon' #set
del obj.name #delete #__del__:析构方法
垃圾回收时触发 ''' # 02 上下文管理协议
# 02 上下文管理协议 '''
# ------------------------------------------------------------
# # 2、 __enter__ 与 __exit__
# # # 这个使用的方法是类似于 with open() as 文件名;
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------
'''
#
# class Foo:
# def __init__(self, name):
# self.name = name
#
# def __enter__(self):
# print("执行了enter")
# return self
#
# def __exit__(self, exc_type, exc_val, exc_tb):
# print("执行了exit")
#
#
#
# with Foo('a.txt') as f:
# print(f)
# print("======1111======")
# print("======2222======")
# print("======3333======")
#
# print("000000000000")
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 执行了enter
# # <__main__.Foo object at 0x000000000228C358>
# # ======1111======
# # ======2222======
# # ======3333======
# # 执行了exit
# # 000000000000
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 3、 __enter__ 与 __exit__ 之文件异常引入
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# # # 这个使用的方法是类似于 with open() as 文件名;
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------
'''
#
# class Foo:
# def __init__(self, name):
# self.name = name
#
# def __enter__(self):
# print("执行了enter")
# return self
#
# def __exit__(self, exc_type, exc_val, exc_tb):
# print("执行了exit")
#
#
#
# with Foo('a.txt') as f:
# print(f)
# print(ffffffffffff)
# print("======1111======")
#
# print("000000000000")
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 执行了enter
# # <__main__.Foo object at 0x000000000297C358>
# # 执行了exit
# # Traceback (most recent call last):
# # File "D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py", line 149, in <module>
# # print(ffffffffffff)
# # NameError: name 'ffffffffffff' is not defined
# #
# # Process finished with exit code 1 '''
# ------------------------------------------------------------
# # 3.1、 __enter__ 与 __exit__ 之文件异常引入1
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# # # 这个使用的方法是类似于 with open() as 文件名;
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------
'''
#
# class Foo:
# def __init__(self, name):
# self.name = name
#
# def __enter__(self):
# print("执行了enter")
# return self
#
# def __exit__(self, exc_type, exc_val, exc_tb):
# print("执行了exit")
# print(exc_type)
# print(exc_val)
# print(exc_tb)
#
#
#
# with Foo('a.txt') as f:
# print(f)
# print("======1111======")
#
# print("000000000000")
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 执行了enter
# # <__main__.Foo object at 0x000000000295C358>
# # ======1111======
# # 执行了exit
# # None
# # None
# # None
# # 000000000000
# #
# # Process finished with exit code 0
# '''
# ------------------------------------------------------------
# # 3.2、 __exit__ 中 exc_type, exc_val, exc_tb 之文件异常引入1
# # # __exit__ 中的 exc_type, exc_val, exc_tb 就是文件异常的信息内容
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# ------------------------------------------------------------
'''
#
# class Foo:
# def __init__(self, name):
# self.name = name
#
# def __enter__(self):
# print("执行了enter")
# return self
#
# def __exit__(self, exc_type, exc_val, exc_tb):
# print("执行了exit")
# print(exc_type)
# print(exc_val)
# print(exc_tb)
#
#
# with Foo('a.txt') as f:
# print(f)
# print(ffffffffffff)
# print("======1111======")
#
# print("000000000000")
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 执行了enter
# # <__main__.Foo object at 0x000000000297C358>
# # 执行了exit
# # Traceback (most recent call last):
# # File "D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py", line 149, in <module>
# # print(ffffffffffff)
# # NameError: name 'ffffffffffff' is not defined
# #
# # Process finished with exit code 1
# '''
# ------------------------------------------------------------
# # 3.3、 __exit__ 中 exc_type, exc_val, exc_tb 之文件异常
# # # __exit__ 中的 exc_type, exc_val, exc_tb 就是文件异常的信息内容
# # # __exit__ 中的返回值设置为True时,文件的异常会结束该文件内容的操作,但是对于
# # # 该操作外的操作信息不会有所影响,仍能够正常运行
# ------------------------------------------------------------
'''
#
# class Foo:
# def __init__(self, name):
# self.name = name
#
# def __enter__(self):
# print("执行了enter")
# return self
#
# def __exit__(self, exc_type, exc_val, exc_tb):
# print("执行了exit")
# print(exc_type)
# print(exc_val)
# print(exc_tb)
# return True
#
#
# with Foo('a.txt') as f:
# print(f)
# print(ffffffffffff)
# print("======1111======")
#
# print("000000000000")
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 执行了enter
# # <__main__.Foo object at 0x0000000002966DD8>
# # 执行了exit
# # <class 'NameError'>
# # name 'ffffffffffff' is not defined
# # <traceback object at 0x00000000039ED608>
# # 000000000000
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 3.4、总结 __enter__ 与 __exit__
# ------------------------------------------------------------
''' '''
# with obj as f:
# '代码块'
#
# 1.with obj ----》触发obj.__enter__(),拿到返回值
#
# 2.as f----->f=返回值、
#
# 3.with obj as f 等同于 f=obj.__enter__()
#
# 4.执行代码块
# 一:没有异常的情况下,整个代码块运行完毕后去触发__exit__,它的三个参数都为None
# 二:有异常的情况下,从异常出现的位置直接触发__exit__
# a:如果__exit__的返回值为True,代表吞掉了异常
# b:如果__exit__的返回值不为True,代表吐出了异常
# c:__exit__的的运行完毕就代表了整个with语句的执行完毕 # 在出现的异常中,
# Trackback: 追踪信息
# NameError: 错误类型; 后面跟的是异常值 ''' # ------------------------------------------------分割线-------------------------------------------------
# day28 描述符应用part1
# day28 描述符应用part1
# day28 描述符应用part1 '''
# ------------------------------------------------------------
# # 4、描述符的应用的引入
# # # test给定的参数中,如果是字符串或者整形数字就输出,否则留报错!显然,
# # # 下面的例子中,是不能够满足该要求的; 下面关于描述符的应用就是为了解决该问题
# ------------------------------------------------------------
'''
#
# def test(x):
# print("-->>",x)
#
#
# test("alex")
# test(1111)
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # -->> alex
# # -->> 1111
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 5、描述符中 __set__ 中的各个参数
# # # __set__中的各个参数:
# # # instance : 修饰的实例本身(下例中,就是实例p1)
# # # value :实例中修饰的那个值(下例中,就是 alex)
# # # self :描述符所在的类本身
# ------------------------------------------------------------
'''
#
# class Typed:
# def __set__(self, instance, value):
# print("【set】方法")
# print("instance参数 【%s】"%instance) # instance 等价于 实例 p1
# print("value参数 【%s】" %value) # 传入的alex
# print("__set__中的self====>>", self) # <__main__.Typed object at 0x00000000022B6B00>
#
# class People:
# name = Typed()
# def __init__(self, name, age, salary):
# self.name = name
# self.age = age
# self.salary = salary
#
#
# p1 = People("alex", "13", 6666)
#
# print("分割线111".center(100, "-"))
# print("p1: ", p1)
# print("People: ", People)
#
# print("p1.__dict__ ", p1.__dict__)
#
# print("分割线111".center(100, "-"))
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【set】方法
# # instance参数 【<__main__.People object at 0x00000000022B6AC8>】
# # value参数 【alex】
# # __set__中的self====>> <__main__.Typed object at 0x00000000022B6B00>
# # -----------------------------------------------分割线111-----------------------------------------------
# # p1: <__main__.People object at 0x00000000022B6AC8>
# # People: <class '__main__.People'>
# # p1.__dict__ {'age': '13', 'salary': 6666}
# # -----------------------------------------------分割线111-----------------------------------------------
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 6、描述符中 __get__ 中的各个参数
# # # __get__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# # # owner :修饰的实例所属的类(下例中,是类People)
# ------------------------------------------------------------
'''
#
# class Typed:
# def __get__(self, instance, owner):
# print("【get】方法")
# print('instance参数 【%s】 ' %instance) # instance 等价于 实例 p1
# print("owner参数 【%s】 "% owner) # 类People
#
# def __set__(self, instance, value):
# print("【set】方法")
# print("instance参数 【%s】"%instance) # instance 等价于 实例 p1
# print("value参数 【%s】" %value) # 传入的alex
# print("__set__中的self====>>", self) # <__main__.Typed object at 0x00000000022B6B00>
#
#
#
# class People:
# name = Typed()
#
# def __init__(self, name, age, salary):
# self.name = name
# self.age = age
# self.salary = salary
#
#
# p1 = People("alex", "13", 6666)
#
# print("分割线111".center(100, "-"))
# print("p1: ", p1)
# print("People: ", People)
# print("p1.__dict__ ", p1.__dict__)
#
# print("分割线222".center(100, "-"))
# p1.name
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【set】方法
# # instance参数 【<__main__.People object at 0x00000000029A6AC8>】
# # value参数 【alex】
# # __set__中的self====>> <__main__.Typed object at 0x00000000029A6B00>
# # -----------------------------------------------分割线111-----------------------------------------------
# # p1: <__main__.People object at 0x00000000029A6AC8>
# # People: <class '__main__.People'>
# # p1.__dict__ {'age': '13', 'salary': 6666}
# # -----------------------------------------------分割线222-----------------------------------------------
# # 【get】方法
# # instance参数 【<__main__.People object at 0x00000000029A6AC8>】
# # owner参数 【<class '__main__.People'>】
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 6.1、描述符中 __get__ 中的各个参数
# # # __get__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# # # owner :修饰的实例所属的类(下例中,是类People)
# ------------------------------------------------------------
'''
#
# class Typed:
# def __get__(self, instance, owner):
# print("【get】方法")
# print('instance参数 【%s】 ' %instance) # instance 等价于 实例 p1
# print("owner参数 【%s】 "% owner) # 类People
#
# def __set__(self, instance, value):
# print("【set】方法")
# print("instance参数 【%s】"%instance) # instance 等价于 实例 p1
# print("value参数 【%s】" %value) # 传入的alex
# print("__set__中的self====>>", self) # <__main__.Typed object at 0x00000000022B6B00>
#
#
#
# class People:
# name = Typed()
#
# def __init__(self, name, age, salary):
# self.name = name
# self.age = age
# self.salary = salary
#
#
# p1 = People("alex", "13", 6666)
#
# print("分割线111".center(100, "-"))
# print("p1: ", p1)
# print("People: ", People)
# print("p1.__dict__ ", p1.__dict__)
#
# print("分割线222".center(100, "-"))
# p1.name
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【set】方法
# # instance参数 【<__main__.People object at 0x00000000029A6AC8>】
# # value参数 【alex】
# # __set__中的self====>> <__main__.Typed object at 0x00000000029A6B00>
# # -----------------------------------------------分割线111-----------------------------------------------
# # p1: <__main__.People object at 0x00000000029A6AC8>
# # People: <class '__main__.People'>
# # p1.__dict__ {'age': '13', 'salary': 6666}
# # -----------------------------------------------分割线222-----------------------------------------------
# # 【get】方法
# # instance参数 【<__main__.People object at 0x00000000029A6AC8>】
# # owner参数 【<class '__main__.People'>】
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 6.2、描述符中 __delete__ 中的各个参数
# # # __delete__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------
'''
#
# class Typed:
# def __get__(self, instance, owner):
# print("【get】方法")
# print('instance参数 【%s】 ' %instance) # instance 等价于 实例 p1
# print("owner参数 【%s】 "% owner) # 类People
#
# def __set__(self, instance, value):
# print("【set】方法")
# print("instance参数 【%s】"%instance) # instance 等价于 实例 p1
# print("value参数 【%s】" %value) # 传入的alex
# print("__set__中的self====>>", self) # <__main__.Typed object at 0x00000000022B6B00>
#
# def __delete__(self, instance):
# print("delete 方法")
# print("instance参数 【%s】"%instance) # instance 等价于 实例 p1
#
#
# class People:
# name = Typed()
#
# def __init__(self, name, age, salary):
# self.name = name
# self.age = age
# self.salary = salary
#
#
# p1 = People("alex", "13", 6666)
#
# print("分割线111".center(100, "-"))
# print("p1: ", p1)
# print("People: ", People)
# print("p1.__dict__ ", p1.__dict__)
#
# print("分割线222".center(100, "-"))
# del p1.name
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【set】方法
# # instance参数 【<__main__.People object at 0x00000000029A6AC8>】
# # value参数 【alex】
# # __set__中的self====>> <__main__.Typed object at 0x00000000029A6B00>
# # -----------------------------------------------分割线111-----------------------------------------------
# # p1: <__main__.People object at 0x00000000029A6AC8>
# # People: <class '__main__.People'>
# # p1.__dict__ {'age': '13', 'salary': 6666}
# # -----------------------------------------------分割线222-----------------------------------------------
# # delete 方法
# # instance参数 【<__main__.People object at 0x00000000029A6AC8>】
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 7、__set__ 使用描述符给给定的实例中传入值
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------
'''
#
# class Typed:
# def __init__(self, key): # key = 'name '
# self.key = key # self.key = 'name'
#
# def __set__(self, instance, value):
# print("【set】方法")
# print("instance参数 【%s】"%instance) # instance 等价于 实例 p1
# print("value参数 【%s】" %value) # 传入的alex
# print("__set__中的self====>>", self) # <__main__.Typed object at 0x00000000022B6B00>
# instance.__dict__[self.key] = value # p1.__dict__[ 'name'] = alex
#
# class People:
# name=Typed('name') # Typed.__set__() == self.__set__()
#
# def __init__(self, name, age, salary):
# self.name = name
# self.age = age
# self.salary = salary
#
#
# p1 = People("alex", "13", 6666)
#
# print("分割线111".center(100, "-"))
# print("p1: ", p1)
# print("People: ", People)
# print("p1.__dict__ ", p1.__dict__)
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【set】方法
# # instance参数 【<__main__.People object at 0x0000000001F27AC8>】
# # value参数 【alex】
# # __set__中的self====>> <__main__.Typed object at 0x0000000001F36B00>
# # -----------------------------------------------分割线111-----------------------------------------------
# # p1: <__main__.People object at 0x0000000001F27AC8>
# # People: <class '__main__.People'>
# # p1.__dict__ {'name': 'alex', 'age': '13', 'salary': 6666}
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 8、__set__ 使用描述符对给定的实例 获取对应的值
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------
'''
#
# class Typed:
# def __init__(self, key): # key = 'name '
# self.key = key # self.key = 'name'
#
# def __get__(self, instance, owner):
# print("【get】方法")
# print('instance参数 【%s】 ' %instance) # instance 等价于 实例 p1
# print("owner参数 【%s】 "% owner) # 类People
# return instance.__dict__[self.key]
#
# def __set__(self, instance, value):
# print("【set】方法")
# print("instance参数 【%s】"%instance) # instance 等价于 实例 p1
# print("value参数 【%s】" %value) # 传入的alex
# # print("__set__中的self====>>", self) # <__main__.Typed object at 0x00000000022B6B00>
# instance.__dict__[self.key] = value # p1.__dict__[ 'name'] = alex
#
# class People:
# name=Typed('name') # Typed.__set__() == self.__set__()
# age =Typed('age')
#
# def __init__(self, name, age, salary):
# self.name = name
# self.age = age
# self.salary = salary
#
#
# p1 = People("alex", "13", 6666)
#
# print("分割线111".center(100, "-"))
# print("p1: ", p1)
# print("People: ", People)
# print("p1.__dict__ ", p1.__dict__)
#
# print("分割线222".center(100, "-"))
# print( "p1.age: ", p1.age)
# print( "p1.name: ",p1.name)
# print( "p1.salary: ",p1.salary)
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【set】方法
# # instance参数 【<__main__.People object at 0x0000000002967E10>】
# # value参数 【alex】
# # 【set】方法
# # instance参数 【<__main__.People object at 0x0000000002967E10>】
# # value参数 【13】
# # -----------------------------------------------分割线111-----------------------------------------------
# # p1: <__main__.People object at 0x0000000002967E10>
# # People: <class '__main__.People'>
# # p1.__dict__ {'name': 'alex', 'age': '13', 'salary': 6666}
# # -----------------------------------------------分割线222-----------------------------------------------
# # 【get】方法
# # instance参数 【<__main__.People object at 0x0000000002967E10>】
# # owner参数 【<class '__main__.People'>】
# # p1.age: 13
# # 【get】方法
# # instance参数 【<__main__.People object at 0x0000000002967E10>】
# # owner参数 【<class '__main__.People'>】
# # p1.name: alex
# # p1.salary: 6666
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 9、使用描述符对给定的实例 的值的设定进行限制1
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------
'''
#
# class Typed:
# def __init__(self, key): # key = 'name ' 以name为例子
# self.key = key # self.key = 'name'
# # self.expected_typed = expected_typed # self.expected_typed = str
#
# def __get__(self, instance, owner):
# print("【get】方法")
# return instance.__dict__[self.key]
#
# def __set__(self, instance, value):
# if not isinstance(value, str ):
# print("你传入的类型不是字符串,错误!!")
# # return # 用return的话,那么程序仍然可以正常运行
# raise TypeError("%s 传入的类型不是str " % (self.key))
# # 符合条件进行添加
# instance.__dict__[self.key] = value # p1.__dict__[ 'name'] = alex
#
#
# class People:
# name=Typed('name') # Typed.__set__() == self.__set__()
# age =Typed('age')
#
# def __init__(self, name, age, salary):
# self.name = name
# self.age = age
# self.salary = salary
#
#
# p1 = People("alex", "13", 6666)
# # p2 = People("egon", 22, 5555) # 会报错,因为这里实例age采用了Typed进行描述,而age要求的是字符串类型
#
# print("分割线111".center(100, "-"))
# print("p1: ", p1)
# print("People: ", People)
# print("p1.__dict__ ", p1.__dict__)
#
# print("分割线222".center(100, "-"))
# print( "p1.age: ", p1.age)
# print( "p1.name: ",p1.name)
# print( "p1.salary: ",p1.salary)
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # -----------------------------------------------分割线111-----------------------------------------------
# # p1: <__main__.People object at 0x0000000002297E48>
# # People: <class '__main__.People'>
# # p1.__dict__ {'name': 'alex', 'age': '13', 'salary': 6666}
# # -----------------------------------------------分割线222-----------------------------------------------
# # 【get】方法
# # p1.age: 13
# # 【get】方法
# # p1.name: alex
# # p1.salary: 6666
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 9.1、使用描述符对给定的实例 的值的设定进行限制2
# # # 对类进行修饰的时候,直接指定数值属性的 类型 ,如name 是str类型
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------
'''
#
# class Typed:
# def __init__(self, key, expected_typed): # key = 'name ' 以name为例子
# self.key = key # self.key = 'name'
# self.expected_typed = expected_typed # self.expected_typed = str
#
# def __get__(self, instance, owner):
# print("【get】方法")
# return instance.__dict__[self.key]
#
# def __set__(self, instance, value,):
# if not isinstance(value, self.expected_typed ):
# print("传入的类型错误!!")
# # return # 用return的话,那么程序仍然可以正常运行
# raise TypeError("%s 传入的类型不是 %s " % (self.key, self.expected_typed))
# # 符合条件进行添加
# instance.__dict__[self.key] = value # p1.__dict__[ 'name'] = alex
#
# def __delete__(self, instance):
# print('delete方法')
# # print('instance参数【%s】' % instance)
# instance.__dict__.pop(self.key)
#
# class People:
# name=Typed('name',str) # Typed.__set__() == self.__set__()
# age =Typed('age', int)
#
# def __init__(self, name, age, salary):
# self.name = name
# self.age = age
# self.salary = salary
#
#
# p1 = People("alex", 11, 6666)
# # p2 = People("egon", "11", 5555) # 会报错,因为这里实例age采用了Typed进行描述,而age要求的是整形,注意这里与上面区别
#
# print("分割线111".center(100, "-"))
# print("p1: ", p1)
# print("People: ", People)
# print("p1.__dict__ ", p1.__dict__)
#
# print("分割线222".center(100, "-"))
# print( "p1.age: ", p1.age)
# print( "p1.name: ",p1.name)
# print( "p1.salary: ",p1.salary)
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # -----------------------------------------------分割线111-----------------------------------------------
# # p1: <__main__.People object at 0x0000000002997E48>
# # People: <class '__main__.People'>
# # p1.__dict__ {'name': 'alex', 'age': 11, 'salary': 6666}
# # -----------------------------------------------分割线222-----------------------------------------------
# # 【get】方法
# # p1.age: 11
# # 【get】方法
# # p1.name: alex
# # p1.salary: 6666
# #
# # Process finished with exit code 0 # 08 类的装饰器的基本原理
# 08 类的装饰器的基本原理 '''
# ------------------------------------------------------------
# # 10、装饰器的引入,修饰函数
# ------------------------------------------------------------
'''
#
# def deco(func):
# print("======deco装饰器运行======")
# return func
#
#
# @deco # 装饰tets()函数 ,相当于 test = deco(test)
# def test():
# print("test函数运行")
# # test() # 这个被屏蔽掉了之后,deco的print函数仍然会触发,但是test()函数中的print就不会运行了
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # ======deco装饰器运行======
# # test函数运行
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 11、装饰器修饰 类
# # # 类中的装饰器的运行的情况,是跟上面的函数的装饰器是有所区别的; 类中的是下运行类,之后再运行装饰器的运行
# # # 而函数中的,是先运行装饰器中的内容,之后再运行函数的内容
# ------------------------------------------------------------
'''
#
# def deco(func):
# print("======deco装饰器运行======")
# return func
#
#
# @deco # 装饰 Foo ,相当于 Foo = deco(Foo)
# class Foo:
# print(" 类 Foo 运行")
#
# print("分割线".center(150,"-"))
# print(Foo.__dict__) # 装饰器只是修饰作用,没有出现在类的字典中
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 类 Foo 运行
# # ======deco装饰器运行======
# # -------------------------------------------------------------------------分割线--------------------------------------------------------------------------
# # {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
# #
# # Process finished with exit code 0 # 09 类的装饰器增强版
# 09 类的装饰器增强版 '''
# ------------------------------------------------------------
# # 12、函数也是有字典的
# ------------------------------------------------------------
'''
#
# def deco(func):
# print("======deco装饰器运行======")
# # obj.x = 1
# # obj.y = 2
# # obj.z = 3
# return func
#
#
# @deco # 装饰tets()函数 ,相当于 test = deco(test)
# def test():
# print("test函数运行")
#
# print( test.__dict__ )
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # ======deco装饰器运行======
# # {}
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 12.1、给函数的字典添加属性
# # # 函数也可以像类一像添加属性,因为函数的本质就是类;python中的一切都是对像
# ------------------------------------------------------------
'''
#
# def deco(obj):
#
# print("======deco装饰器运行======")
# obj.x = 1
# obj.y = 2
# obj.z = 3
# return obj
#
#
# @deco # 装饰tets()函数 ,相当于 test = deco(test)
# def test():
# print("test函数运行")
#
# print("分割线".center(150,"-"))
# test()
# print(" test.__dict__ ", test.__dict__ )
# test()
# test.name = "新加的name"
# print(" test.__dict__ ", test.__dict__ )
# print(" type(test) ", type(test) )
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # ======deco装饰器运行======
# # -------------------------------------------------------------------------分割线--------------------------------------------------------------------------
# # test函数运行
# # test.__dict__ {'x': 1, 'y': 2, 'z': 3}
# # test函数运行
# # test.__dict__ {'x': 1, 'y': 2, 'z': 3, 'name': '新加的name'}
# # type(test) <class 'function'>
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 13、使用装饰器给类中的字典添加属性
# ------------------------------------------------------------
'''
#
# def deco(obj):
#
# print("======deco装饰器运行======")
# obj.x = 1
# obj.y = 2
# obj.z = 3
# return obj
#
#
# @deco # 装饰tets()函数 ,相当于 test = deco(test)
# class Foo:
# print("Foo 运行")
#
#
# print("分割线".center(150,"-"))
#
# print(" Foo.__dict__ ", Foo.__dict__ )
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # Foo 运行
# # ======deco装饰器运行======
# # -------------------------------------------------------------------------分割线--------------------------------------------------------------------------
# # Foo.__dict__ {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2, 'z': 3}
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 14、使用装饰器给类中的字典添加属性
# # # 只能在装饰器中内部给定值的情况
# ------------------------------------------------------------
'''
#
# def Typed(**kwargs):
# def deco(obj):
# print("======deco装饰器运行======")
# obj.x = 1
# obj.y = 2
# obj.z = 3
# return obj
# return deco
#
#
# @Typed(x="我是随便写的") # 1、Typed(x="我是随便写的")--》deco 2、deco--》Foo = deco(Foo)
# class Foo:
# print("Foo 运行")
#
#
# print("分割线".center(150,"-"))
#
# print(" Foo.__dict__ ", Foo.__dict__ )
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # Foo 运行
# # ======deco装饰器运行======
# # -------------------------------------------------------------------------分割线--------------------------------------------------------------------------
# # Foo.__dict__ {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2, 'z': 3}
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 14.1、使用装饰器给类中的字典添加属性1
# # # 解决只能在装饰器中内部给定值的情况
# ------------------------------------------------------------
''' # def Typed(**kwargs):
# def deco(obj):
# print("======deco装饰器运行======")
# print(obj)
# for key, val in kwargs.items():
# print("key = %s, type = %s"%(key, type(key)))
# # obj.key = val # 这种方式是不可以的,因为key会被当作是实例的属性名
# # obj.__dict__[key] = val # 报错!从原理上是可以这么做的,但是编译器里是不支持这种做法! TypeError: 'mappingproxy' object does not support item assignment
# setattr(obj, key, val)
# return obj
# return deco
#
#
# @Typed(x=1, y =2, z =3) # 1、Typed(x="我是随便写的")--》deco 2、deco--》Foo = deco(Foo)
# class Foo:
# print("Foo 运行")
#
#
# print("分割线2222".center(150,"-"))
#
# print(" Foo.__dict__ ", Foo.__dict__ )
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # Foo 运行
# # ======deco装饰器运行======
# # key = x, type = <class 'str'>
# # key = y, type = <class 'str'>
# # key = z, type = <class 'str'>
# # -----------------------------------------------------------------------分割线2222------------------------------------------------------------------------
# # Foo.__dict__ {'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'x': 1, 'y': 2, 'z': 3}
# #
# # Process finished with exit code 0 # 11 装饰器的应用
# 11 装饰器的应用 '''
# ------------------------------------------------------------
# # 15、装饰器的应用(与前面的序号10对比)
# ------------------------------------------------------------
'''
#
#
# class Typed:
# def __init__(self,key,expected_type):
# self.key=key
# self.expected_type=expected_type
#
# def __get__(self, instance, owner):
# print('get方法')
# # print('instance参数【%s】' %instance)
# # print('owner参数【%s】' %owner)
# return instance.__dict__[self.key]
#
# def __set__(self, instance, value):
# print('set方法')
# # print('instance参数【%s】' % instance)
# # print('value参数【%s】' % value)
# # print('====>',self)
# if not isinstance(value,self.expected_type):
# # print('你传入的类型不是字符串,错误')
# # return
# raise TypeError('%s 传入的类型不是%s' %(self.key,self.expected_type))
# instance.__dict__[self.key]=value
#
# def __delete__(self, instance):
# print('delete方法')
# # print('instance参数【%s】' % instance)
# instance.__dict__.pop(self.key)
#
#
# def deco(**kwargs): # kwargs={'name':str,'age':int}
# def wrapper(obj): # obj=People
# for key,val in kwargs.items(): # (('name',str),('age',int))
# setattr(obj,key,Typed(key,val))
# # setattr(People,'name',Typed('name',str)) #People.name=Typed('name',str)
# return obj
# return wrapper
#
#
# @deco(name=str,age=int) # @wrapper ===>People=wrapper(People)
# class People:
# name='我是谁,我是谁' # 这里会被装饰器所覆盖,因此无效
# # name=Typed('name',str) # 装饰器就是为了实现该功能
# # age=Typed('age',int) # 装饰器就是为了实现该功能
#
# def __init__(self,name,age,salary):
# self.name=name
# self.age=age
# self.salary=salary
#
# p1 = People("alex", 11, 6666)
# # p2 = People("egon", '22', 5555) # 会报错,因为这里实例age采用了Typed进行描述,而age要求的是整数类型
#
# print("分割线111".center(100, "-"))
# print("p1: ", p1)
# print("People: ", People)
# print("p1.__dict__ ", p1.__dict__)
# print("People.__dict__ ", People.__dict__)
#
# print("分割线222".center(100, "-"))
# print( "p1.age: ", p1.age)
# print( "p1.name: ",p1.name)
# print( "p1.salary: ",p1.salary)
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # set方法
# # set方法
# # -----------------------------------------------分割线111-----------------------------------------------
# # p1: <__main__.People object at 0x0000000002957E48>
# # People: <class '__main__.People'>
# # p1.__dict__ {'name': 'alex', 'age': 11, 'salary': 6666}
# # People.__dict__ {'__module__': '__main__', 'name': <__main__.Typed object at 0x0000000002966B00>, '__init__': <function People.__init__ at 0x00000000039EEAE8>, '__dict__': <attribute '__dict__' of 'People' objects>, '__weakref__': <attribute '__weakref__' of 'People' objects>, '__doc__': None, 'age': <__main__.Typed object at 0x0000000002957E10>}
# # -----------------------------------------------分割线222-----------------------------------------------
# # get方法
# # p1.age: 11
# # get方法
# # p1.name: alex
# # p1.salary: 6666
# #
# # Process finished with exit code 0 # 11 自定制property
# 11 自定制property '''
# ------------------------------------------------------------
# # 16、property 的使用
# # # property() 函数的作用是在新式类中返回属性值。
# # # 下面例子中,(原)r1.area()-->>(现)r1.area
# ------------------------------------------------------------
'''
#
# class Room:
# def __init__(self, name, width, length):
# self.name = name
# self.width = width
# self.length = length
#
# @property # (Room类)area=property((Room类)area)
# def area(self):
# print("【area】")
# return self.width * self.length
#
# def area1(self):
# print("【area1】")
# return self.width * self.length
#
#
# r1 = Room('厕所', 1, 1)
#
# print(r1.area) # 'area': <property object at 0x00000000020E8688>
# print(r1.area1()) # 'area1': <function Room.area1 at 0x00000000039EE8C8>,
#
# print("r1.__dict__: ", r1.__dict__)
# print("Room.__dict__: ", Room.__dict__)
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【area】
# # 1
# # 【area1】
# # 1
# # r1.__dict__: {'name': '厕所', 'width': 1, 'length': 1}
# # Room.__dict__: {'__module__': '__main__', '__init__': <function Room.__init__ at 0x00000000039EE7B8>, 'area': <property object at 0x00000000020E8688>, 'area1': <function Room.area1 at 0x00000000039EE8C8>, '__dict__': <attribute '__dict__' of 'Room' objects>, '__weakref__': <attribute '__weakref__' of 'Room' objects>, '__doc__': None}
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 17、property引入 , 类的装饰器
# ------------------------------------------------------------
'''
#
# class Lazyproperty:
# def __init__(self, func):
# print("=======>>>",func) # <function Room.area at 0x00000000039EE8C8>
#
#
# class Room:
# def __init__(self, name, width, length):
# self.name = name
# self.width = width
# self.length = length
#
# @Lazyproperty # (Room类)area = Lazyproperty( (Room类)area )
# def area(self):
# print("【area】")
# return self.width * self.length
#
# def area1(self):
# print("【area1】")
# return self.width * self.length
#
#
# print("分割线11".center(150,"-"))
# r1 = Room('厕所', 1, 1)
#
# print("分割线22".center(150,"-"))
# print(r1.area) # <__main__.Lazyproperty object at 0x00000000029CC358>
# print("分割线33".center(150,"-"))
# print(r1.area1())
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # =======>>> <function Room.area at 0x00000000039EE8C8>
# # ------------------------------------------------------------------------分割线11-------------------------------------------------------------------------
# # ------------------------------------------------------------------------分割线22-------------------------------------------------------------------------
# # <__main__.Lazyproperty object at 0x00000000029CC358>
# # ------------------------------------------------------------------------分割线33-------------------------------------------------------------------------
# # 【area1】
# # 1
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 18、property装饰器初步 , 类的装饰器
# # # print(r1.area.func(r1)) 实现了基本的装饰器功能
# ------------------------------------------------------------
'''
#
# class Lazyproperty:
# def __init__(self, func):
# # 运行时,先程序自己先预读了; <function Room.area at 0x00000000039EE8C8>
# # 这里,func实际上接收的是 Room 类 中的 area函数的地址
# print("=======>>>",func)
# self.func = func
#
# class Room:
# def __init__(self, name, width, length):
# self.name = name
# self.width = width
# self.length = length
#
# @Lazyproperty # (Room类)area = Lazyproperty( (Room类)area )
# def area(self):
# '''
# 运行@Lazyproperty 的时候,相当于进行实例化,形式如下: (Room类)area = Lazyproperty( (Room类)area ),其中,area传入的是一个Room 类中的一个函数的地址
#
# :return:
# '''
# print("【area】")
# return self.width * self.length
#
# def area1(self):
# print("【area1】")
# return self.width * self.length
#
#
# print("分割线11".center(150,"-"))
# r1 = Room('厕所', 1, 1)
# print(r1) # <__main__.Room object at 0x0000000002377A90>
#
# print("分割线22".center(150,"-"))
# # property装饰器初步,我们要实现的就是 r1.area就可以实现该功能
# # r1.area.func(r1) 如何理解:
# print(r1.area) # <__main__.Lazyproperty object at 0x0000000001DBD128>
# print(r1.area.func) # <function Room.area at 0x00000000039EE8C8>
# print(r1.area.func(r1))
# print("分割线33".center(150,"-"))
# print(r1.area1())
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # =======>>> <function Room.area at 0x00000000039EE8C8>
# # ------------------------------------------------------------------------分割线11-------------------------------------------------------------------------
# # ------------------------------------------------------------------------分割线22-------------------------------------------------------------------------
# # 【area】
# # 1
# # ------------------------------------------------------------------------分割线33-------------------------------------------------------------------------
# # 【area1】
# # 1
# #
# # Process finished with exit code 0
#
#
# '''
# ------------------------------------------------------------
# # 18.1、property装饰器初步之 __get__ , 类的装饰器
# # # 目标: print(r1.area.func(r1)) ==>> 等价于执行 print(r1.area)
# # # __get__ 接受被修饰对象中的实例,
# ------------------------------------------------------------
'''
#
# class Lazyproperty:
# def __init__(self, func):
# print("=======>>>",func) # Room 类定义的函数,def area ; <function Room.area at 0x00000000039EE8C8>
# self.func = func
#
# def __get__(self, instance, owner):
# print("【get】")
# print("instance: ", instance) # 实际上,就是 Room 类产生的实例 r1; <__main__.Room object at 0x0000000002267A58>
# print("owner: ", owner) # Room 类;, class '__main__.Room'>
#
#
# class Room:
# x = Lazyproperty('这个是用来测试的')
#
# def __init__(self, name, width, length):
# self.name = name
# self.width = width
# self.length = length
#
# @Lazyproperty # 新(Room类)area = Lazyproperty( 旧(Room类)area )
# def area(self):
# print("【area】")
# return self.width * self.length
#
# def area1(self):
# print("【area1】")
# return self.width * self.length
#
#
# print("分割线11".center(150,"-"))
# r1 = Room('厕所', 1, 1)
#
# print("分割线22".center(150,"-"))
# print(r1.area) # 相当于Lazyproperty的一个实例; 'area': <__main__.Lazyproperty object at 0x0000000002297A90>,
#
#
# print("分割线33".center(150,"-"))
# print("r1.__dict__: ", r1.__dict__)
# print("Room.__dict__: ", Room.__dict__)
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # =======>>> 这个是用来测试的
# # =======>>> <function Room.area at 0x00000000039EE950>
# # ------------------------------------------------------------------------分割线11-------------------------------------------------------------------------
# # ------------------------------------------------------------------------分割线22-------------------------------------------------------------------------
# # <__main__.Room object at 0x0000000002267A58>
# # 【get】
# # instance: <__main__.Room object at 0x0000000002267A58>
# # owner: <class '__main__.Room'>
# # None
# # ------------------------------------------------------------------------分割线33-------------------------------------------------------------------------
# # r1.__dict__: {'name': '厕所', 'width': 1, 'length': 1}
# # Room.__dict__: {'__module__': '__main__', 'x': <__main__.Lazyproperty object at 0x0000000001DBD128>, '__init__': <function Room.__init__ at 0x00000000039EE8C8>, 'area': <__main__.Lazyproperty object at 0x0000000002267A90>, 'area1': <function Room.area1 at 0x00000000039EE9D8>, '__dict__': <attribute '__dict__' of 'Room' objects>, '__weakref__': <attribute '__weakref__' of 'Room' objects>, '__doc__': None}
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 18.2、property装饰器“实现”之 __get__ 返回运行的内容, 类的装饰器
# # # 目标(实现): print(r1.area.func(r1)) ==>> 等价于执行 print(r1.area)
# # # __get__ 接受被修饰对象中的实例,
# ------------------------------------------------------------
'''
#
# class Lazyproperty:
# def __init__(self, func):
# print("=======>>>",func) # Room 类定义的函数,def area ; <function Room.area at 0x00000000039EE8C8>
# self.func = func
#
# def __get__(self, instance, owner):
# print("【get】")
# print("instance: ", instance) # 实际上,就是 Room 类产生的实例 r1; <__main__.Room object at 0x0000000002267A58>
# print("owner: ", owner) # Room 类;, class '__main__.Room'>
# res = self.func(instance) # 相当于 Room 类中,运行 res = area1( r1 )
# return res
#
# class Room:
# x = Lazyproperty('这个是用来测试的')
#
# def __init__(self, name, width, length):
# self.name = name
# self.width = width
# self.length = length
#
# @Lazyproperty # 新(Room类)area = Lazyproperty( 旧(Room类)area )
# def area(self): # self 代表的是实例本身;这里 self == 实例r1
# '''
# 运行过程: 进行 Lazyproperty 中的 __get__ 函数 --> self.func(instance) == Room 类中的 area( r1 ) ->
# 运行Room 类中的 area( r1 )的内容 --> res 得到运行结果 ( Lazyproperty 中的 __get__ 函数)-->
# return res
# :return:
# '''
#
# print("【area】")
# return self.width * self.length
#
# def area1(self):
# print("【area1】")
# return self.width * self.length
#
#
# print("分割线11".center(150,"-"))
# r1 = Room('厕所', 1, 1)
#
# print("分割线22".center(150,"-"))
# print(r1.area) # 相当于Lazyproperty的一个实例; 'area': <__main__.Lazyproperty object at 0x0000000002297A90>,
#
# print(r1.area1() ) # 运行过程: r1.area1() --> Room 类 --> area1(r1)运行 --> 得到返回值
# print("分割线33".center(150,"-"))
# print("r1.__dict__: ", r1.__dict__)
# print("Room.__dict__: ", Room.__dict__)
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # =======>>> 这个是用来测试的
# # =======>>> <function Room.area at 0x00000000039EE950>
# # ------------------------------------------------------------------------分割线11-------------------------------------------------------------------------
# # ------------------------------------------------------------------------分割线22-------------------------------------------------------------------------
# # 【get】
# # instance: <__main__.Room object at 0x0000000002997A90>
# # owner: <class '__main__.Room'>
# # 【area】
# # 1
# # 【area1】
# # 1
# # ------------------------------------------------------------------------分割线33-------------------------------------------------------------------------
# # r1.__dict__: {'name': '厕所', 'width': 1, 'length': 1}
# # Room.__dict__: {'__module__': '__main__', 'x': <__main__.Lazyproperty object at 0x00000000029A6B00>, '__init__': <function Room.__init__ at 0x00000000039EE8C8>, 'area': <__main__.Lazyproperty object at 0x0000000002997E10>, 'area1': <function Room.area1 at 0x00000000039EE9D8>, '__dict__': <attribute '__dict__' of 'Room' objects>, '__weakref__': <attribute '__weakref__' of 'Room' objects>, '__doc__': None}
# #
# # Process finished with exit code 0
#
# '''
# ------------------------------------------------------------
# # 18.3、property装饰器“实现” (简洁版)
# ------------------------------------------------------------
'''
#
# class Lazyproperty:
# def __init__(self, func): # 传入的是 Room 类定义的函数地址,
# self.func = func
#
# def __get__(self, instance, owner):
# '''
#
# :param instance: 实例 r1
# :param owner: Room 类
# :return:
# '''
# print("【get】")
# res = self.func(instance)
# return res
#
#
# class Room:
# def __init__(self, name, width, length):
# self.name = name
# self.width = width
# self.length = length
#
# @Lazyproperty # 新(Room类)area = Lazyproperty( 旧(Room类)area )
# def area(self): # self 代表的是实例本身;这里 self == 实例r1
# '''
# 运行过程: 进行 Lazyproperty 中的 __get__ 函数 --> self.func(instance) == Room 类中的 area( r1 ) ->
# 运行Room 类中的 area( r1 )的内容 --> res 得到运行结果 ( Lazyproperty 中的 __get__ 函数)-->
# return res
# :return:
# '''
#
# print("【area】")
# return self.width * self.length
#
# def area1(self):
# print("【area1】")
# return self.width * self.length
#
#
# print("分割线11".center(150,"-"))
# r1 = Room('厕所', 1, 1)
#
# print("分割线22".center(150,"-"))
# print(r1.area) # r1.area 相当于Lazyproperty的一个实例
# print(r1.area1() ) # 运行过程: r1.area1() --> Room 类 --> area1(r1)运行 --> 得到返回值
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # ------------------------------------------------------------------------分割线11-------------------------------------------------------------------------
# # ------------------------------------------------------------------------分割线22-------------------------------------------------------------------------
# # 【get】
# # 【area】
# # 1
# # 【area1】
# # 1
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 18.4、property装饰器“实现” (简洁版) 与 内置的property装饰器对比1
# ------------------------------------------------------------
'''
#
# class Lazyproperty:
# def __init__(self, func): # 传入的是 Room 类定义的函数地址,
# self.func = func
#
# def __get__(self, instance, owner):
# '''
#
# :param instance: 实例 r1
# :param owner: Room 类
# :return:
# '''
# print("【get】")
# res = self.func(instance)
# return res
#
#
# class Room:
# def __init__(self, name, width, length):
# self.name = name
# self.width = width
# self.length = length
#
# @Lazyproperty # 新(Room类)area = Lazyproperty( 旧(Room类)area )
# def area(self): # self 代表的是实例本身;这里 self == 实例r1
# '''
# 运行过程: 进行 Lazyproperty 中的 __get__ 函数 --> self.func(instance) == Room 类中的 area( r1 ) ->
# 运行Room 类中的 area( r1 )的内容 --> res 得到运行结果 ( Lazyproperty 中的 __get__ 函数)-->
# return res
# :return:
# '''
#
# print("【area】")
# return self.width * self.length
#
# @property
# def area1(self):
# print("【area1】")
# return self.width * self.length
#
#
# print("分割线11".center(150,"-"))
# r1 = Room('厕所', 1, 1)
#
# print("分割线22".center(150,"-"))
# print(r1.area) # r1.area 相当于Lazyproperty的一个实例
# print(r1.area1 ) # 运行过程: r1.area1() --> Room 类 --> area1(r1)运行 --> 得到返回值
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # ------------------------------------------------------------------------分割线11-------------------------------------------------------------------------
# # ------------------------------------------------------------------------分割线22-------------------------------------------------------------------------
# # 【get】
# # 【area】
# # 1
# # 【area1】
# # 1
# #
# # Process finished with exit code 0
# # 12 自定制property流程分析
# 12 自定制property流程分析
# ?????
# ?????
# ????? '''
# ------------------------------------------------------------
# # 19、property装饰器,之类调用静态属性 对比
# # # “实现” (简洁版) 与 内置的property装饰器 说明:
Room调用 property装饰器 修饰的函数成为静态属性之后,print(Room.area1) 返回的是一个 <property object at 0x00000000027D8778>
而自己实现的 Lazyproperty 装饰器中,会出错 # ------------------------------------------------------------
'''
#
# class Lazyproperty:
# def __init__(self, func): # 传入的是 Room 类定义的函数地址,
# self.func = func
#
# def __get__(self, instance, owner):
# '''
#
# :param instance: 实例 r1
# :param owner: Room 类
# :return:
# '''
# print("【get】")
# print("instance: ", instance) # 实际上,就是 Room 类产生的实例 r1; <__main__.Room object at 0x0000000002267A58>
# print("owner: ", owner) # Room 类;, class '__main__.Room'>
# res = self.func(instance)
# return res
#
#
# class Room:
# def __init__(self, name, width, length):
# self.name = name
# self.width = width
# self.length = length
#
# @Lazyproperty # 新(Room类)area = Lazyproperty( 旧(Room类)area )
# def area(self): # self 代表的是实例本身;这里 self == 实例r1
# '''
# 运行过程: 进行 Lazyproperty 中的 __get__ 函数 --> self.func(instance) == Room 类中的 area( r1 ) ->
# 运行Room 类中的 area( r1 )的内容 --> res 得到运行结果 ( Lazyproperty 中的 __get__ 函数)-->
# return res
# :return:
# '''
#
# print("【area】")
# return self.width * self.length
#
# @property
# def area1(self):
# print("【area1】")
# return self.width * self.length
#
#
# print("分割线11".center(150,"-"))
# r1 = Room('厕所', 1, 1)
#
# print("分割线22".center(150,"-"))
# print(Room.area1)
#
# print("分割线33".center(150,"-"))
# print(Room.area)
#
#
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # ------------------------------------------------------------------------分割线11-------------------------------------------------------------------------
# # ------------------------------------------------------------------------分割线22-------------------------------------------------------------------------
# # <property object at 0x00000000027B8F98>
# # ------------------------------------------------------------------------分割线33-------------------------------------------------------------------------
# # 【get】
# # instance: None
# # owner: <class '__main__.Room'>
# # 【area】
# # Traceback (most recent call last):
# # File "D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py", line 1886, in <module>
# # print(Room.area)
# # File "D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py", line 1851, in __get__
# # res = self.func(instance)
# # File "D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py", line 1871, in area
# # return self.width * self.length
# # AttributeError: 'NoneType' object has no attribute 'width'
# #
# # Process finished with exit code 1 '''
# ------------------------------------------------------------
# # 19.1、property装饰器,之类调用静态属性,实现property的完整功能( 类无法调用静态属性)
# # # “实现” (简洁版) 与 内置的property装饰器 说明:
Room调用 property装饰器 修饰的函数成为静态属性之后,print(Room.area1) 返回的是
一个 <property object at 0x00000000027D8778>; 实际上,这个就是 Property 对象本身
而自己实现的 Lazyproperty 装饰器中,会出错 # ------------------------------------------------------------
'''
#
# class Lazyproperty:
# def __init__(self, func): # 传入的是 Room 类定义的函数地址,
# self.func = func
#
# def __get__(self, instance, owner):
# '''
# :self : 是 类 Lazyproperty
# :param instance: 实例 r1
# :param owner: Room 类
# :return:
# '''
# print("【get】")
# # print("instance: ", instance) # 类调用的时候,返回值是一个 None
# # print("owner: ", owner) # Room 类;, class '__main__.Room'>
# if instance is None:
# return self
# res = self.func(instance)
# return res
#
#
# class Room:
# def __init__(self, name, width, length):
# self.name = name
# self.width = width
# self.length = length
#
# @Lazyproperty # 新(Room类)area = Lazyproperty( 旧(Room类)area )
# def area(self): # self 代表的是实例本身;这里 self == 实例r1
# '''
# 运行过程: 进行 Lazyproperty 中的 __get__ 函数 --> self.func(instance) == Room 类中的 area( r1 ) ->
# 运行Room 类中的 area( r1 )的内容 --> res 得到运行结果 ( Lazyproperty 中的 __get__ 函数)-->
# return res
# :return:
# '''
#
# print("【area】")
# return self.width * self.length
#
# @property
# def area1(self):
# print("【area1】")
# return self.width * self.length
#
#
# print("分割线11".center(150,"-"))
# r1 = Room('厕所', 1, 1)
#
# print("分割线22".center(150,"-"))
# print("Room.area1: ", Room.area1)
#
# print("分割线33".center(150,"-"))
# print("Room.area: ", Room.area)
#
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # ------------------------------------------------------------------------分割线11-------------------------------------------------------------------------
# # ------------------------------------------------------------------------分割线22-------------------------------------------------------------------------
# # Room.area1: <property object at 0x0000000001D98778>
# # ------------------------------------------------------------------------分割线33-------------------------------------------------------------------------
# # 【get】
# # Room.area: <__main__.Lazyproperty object at 0x0000000002986DD8>
# #
# # Process finished with exit code 0 # 13 实现延迟计算;
# 13 实现延迟计算; '''
# ------------------------------------------------------------
# # 20、__name__获取函数的名字
# # # 用来获取运行的模块的名字, 或者对应的对象的名字(类是获取不到名字的)
# ------------------------------------------------------------
'''
#
# class Lazyproperty:
# def __init__(self, func): # 传入的是 Room 类定义的函数地址,
# self.func = func
# print("【func.__name__】 ", func.__name__)
# print("【self.func.__name__】 ", self.func.__name__)
#
#
# class Room:
# def __init__(self, name, width, length):
# self.name = name
# self.width = width
# self.length = length
#
#
# @Lazyproperty
# def area(self):
# pass
#
# @property
# def area1(self):
# pass
#
# def test(self):
# pass
#
# def info():
# pass
#
# print("分割线11".center(150,"-"))
# r1 = Room('厕所', 1, 1)
#
# # print(r1.__name__) # 报错, 这个是无法获取明名的
# # print(r1.area.__name__) # 报错, 这个是无法获取明名的
#
# print(Lazyproperty.__name__)
# print(Room.__name__)
# print("当前的运行的名字", __name__)
#
#
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【func.__name__】 area
# # 【self.func.__name__】 area
# # ------------------------------------------------------------------------分割线11-------------------------------------------------------------------------
# # Lazyproperty
# # Room
# # 当前的运行的名字 __main__
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 21、property装饰器,之类调用静态属性,实现property的完整功能
# # # “实现” (简洁版) 与 内置的property装饰器
# ------------------------------------------------------------
'''
#
# class Lazyproperty:
# def __init__(self, func):
# '''
#
# :param func: 传入的是 Room 类定义的函数地址,
# '''
# self.func = func
#
# def __get__(self, instance, owner):
# '''
#
# :self : 是 类 Lazyproperty
# :param instance: 实例 r1; 类调用的时候,返回值是一个 None
# :param owner: Room 类
# :return:
# '''
# print("【get】")
# if instance is None:
# return self
# res = self.func(instance)
# setattr(instance, self.func.__name__, res) # 实现延迟计算; 当传入的值是重复的时候,
# return res
#
#
# class Room:
# def __init__(self, name, width, length):
# self.name = name
# self.width = width
# self.length = length
#
# @Lazyproperty # 新(Room类)area = Lazyproperty( 旧(Room类)area )
# def area(self): # self 代表的是实例本身;这里 self == 实例r1
# '''
# 运行过程: 进行 Lazyproperty 中的 __get__ 函数 --> self.func(instance) == Room 类中的 area( r1 ) ->
# 运行Room 类中的 area( r1 )的内容 --> res 得到运行结果 ( Lazyproperty 中的 __get__ 函数)-->
# return res
# :return:
# '''
#
# print("【area】")
# return self.width * self.length
#
# @property
# def area1(self):
# print("【area1】")
# return self.width * self.length
#
#
# print("分割线11".center(150,"-"))
# r1 = Room('厕所', 1, 1)
#
# print("分割线22".center(150,"-"))
# print("Room.area1: ", Room.area1)
#
# print("分割线33".center(150,"-"))
# print("Room.area: ", Room.area)
#
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # ------------------------------------------------------------------------分割线11-------------------------------------------------------------------------
# # ------------------------------------------------------------------------分割线22-------------------------------------------------------------------------
# # Room.area1: <property object at 0x0000000001E18778>
# # ------------------------------------------------------------------------分割线33-------------------------------------------------------------------------
# # 【get】
# # Room.area: <__main__.Lazyproperty object at 0x0000000002976DA0>
# #
# # Process finished with exit code 0 '''
# # # classmethod staticmethod 装饰器的实现
# # # 见:
# # # 面向对象进阶 - linhaifeng - 博客园
# https://www.cnblogs.com/linhaifeng/articles/6204014.html#_label12
''' #
# 15 元类介绍
# 15 元类介绍 '''
# ------------------------------------------------------------
# # 21.1、元类的引入
# # # python中一切皆为对象。类的本身也是一个对象,由 type 产生
# ------------------------------------------------------------
'''
#
# class Foo:
# pass
#
# f1 = Foo() # 1是通过Foo类实例化的对象
#
# print(type(f1))
# print(type(Foo))
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # <class '__main__.Foo'>
# # <class 'type'>
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 22、type 元类来产生 类 # # # FFo = type("FFo", (object,), {'x': 1})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo", 类名
# # # 位置2:(object,), 对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3:{'x': 1}, 类的属性字典
# ------------------------------------------------------------
''' #
# class Foo:
# def __init__(self):
# pass
#
#
# FFo = type("FFo", (object,), {'x': 1})
#
# print(Foo)
# print(Foo.__dict__)
#
# print("分割线".center(150, "-"))
# print(FFo)
# print(FFo.__dict__)
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # <class '__main__.Foo'>
# # {'__module__': '__main__', '__init__': <function Foo.__init__ at 0x00000000039EE7B8>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
# # -------------------------------------------------------------------------分割线--------------------------------------------------------------------------
# # <class '__main__.FFo'>
# # {'x': 1, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'FFo' objects>, '__weakref__': <attribute '__weakref__' of 'FFo' objects>, '__doc__': None}
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 22.1、type 元类来产生 类
# # # 给类中添加类的初始化属数,类的数值属性, 类的函数属性 # # # FFo = type("FFo", (object,), {'x':1, '__init__':__init__, 'test':test})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo", 类名
# # # 位置2:(object,), 对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3: {'x':1, '__init__':__init__, 'test':test}, 类的属性字典
# # # 'x':1 相当于在类中定义数值属性 x = 1
# # # '__init__':__init__ 相当于在类中定义类初化始的函数属性 def __init__(self)
# # # 'test':test 相当于在类中定义类的函数属性 def test(self)
# ------------------------------------------------------------
'''
#
# class Foo:
# def __init__(self):
# pass
#
# print(Foo)
# print(Foo.__dict__)
#
# def __init__(self, name, age):
# self.name = name
# self.age = age
#
# def test(self):
# print("【test】")
#
#
# print("分割线".center(150,"-"))
# FFo = type("FFo", (object,), {'x':1, '__init__':__init__, 'test':test})
#
# print(FFo)
# print(FFo.__dict__) # 属性字典里头找到了FFo类的定义的属性
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # <class '__main__.Foo'>
# # {'__module__': '__main__', '__init__': <function Foo.__init__ at 0x00000000039EE7B8>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
# # -------------------------------------------------------------------------分割线--------------------------------------------------------------------------
# # <class '__main__.FFo'>
# # {'x': 1, '__init__': <function __init__ at 0x0000000002965620>, 'test': <function test at 0x00000000039EE840>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'FFo' objects>, '__weakref__': <attribute '__weakref__' of 'FFo' objects>, '__doc__': None}
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 22.2、type 元类产生的类进行 实例化
# # # 给类中添加类的初始化属数,类的数值属性, 类的函数属性 # # # FFo = type("FFo", (object,), {'x':1, '__init__':__init__, 'test':test})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo", 类名
# # # 位置2:(object,), 对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3: {'x':1, '__init__':__init__, 'test':test}, 类的属性字典
# # # 'x':1 相当于在类中定义数值属性 x = 1
# # # '__init__':__init__ 相当于在类中定义类初化始的函数属性 def __init__(self)
# # # 'test':test 相当于在类中定义类的函数属性 def test(self)
# ------------------------------------------------------------
'''
#
# def __init__(self, name, age):
# self.name = name
# self.age = age
#
#
# def test(self):
# print("【test】")
#
#
# print("分割线".center(150,"-"))
# FFo = type("FFo", (object,), {'x':1, '__init__':__init__, 'test':test})
#
# ff1 = FFo("我是ff1", "999")
# print("ff1.__dict__: ", ff1.__dict__)
# ff1.name = "这是啥一"
# ff1.sex = "None"
# ff1.test()
#
# print("分割线".center(150,"-"))
# print("ff1.name ", ff1.name)
# print("ff1.sex ", ff1.sex)
# # 可以看到,通过 type 产生的类能够进行实例化,这个与使用class定义的无差别
# print("ff1.__dict__: ", ff1.__dict__)
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # -------------------------------------------------------------------------分割线--------------------------------------------------------------------------
# # ff1.__dict__: {'name': '我是ff1', 'age': '999'}
# # 【test】
# # -------------------------------------------------------------------------分割线--------------------------------------------------------------------------
# # ff1.name 这是啥一
# # ff1.sex None
# # ff1.__dict__: {'name': '这是啥一', 'age': '999', 'sex': 'None'}
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 22.3、类的产生总结
# # # 类的产生有两种方式,1、通过 class来定义类; 2、通过type来产生类
# ------------------------------------------------------------
''' # 16 自定义元类
# 16 自定义元类 '''
# ------------------------------------------------------------
# # 23、自定义元类引入,元类定义自己的元类type
# ------------------------------------------------------------
'''
#
# class Foo():
# def __init__(self, name): # FFo 类定义自己的元类
# self.name = name
#
# def test(self):
# print("Foo【test】")
#
# class FFo(metaclass=type): # FFo 类定义自己的元类; 相当于触发了 type('Foo', (object, ){})
# def __init__(self, name):
# self.name = name
#
# def test(self):
# print("FFo【test】")
#
#
# print("Foo.__dict__: ", Foo.__dict__)
# print("FFo.__dict__: ", FFo.__dict__)
#
# print(Foo)
# print(FFo)
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # Foo.__dict__: {'__module__': '__main__', '__init__': <function Foo.__init__ at 0x00000000039EE7B8>, 'test': <function Foo.test at 0x00000000039EE840>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
# # FFo.__dict__: {'__module__': '__main__', '__init__': <function FFo.__init__ at 0x00000000039EE8C8>, 'test': <function FFo.test at 0x00000000039EE950>, '__dict__': <attribute '__dict__' of 'FFo' objects>, '__weakref__': <attribute '__weakref__' of 'FFo' objects>, '__doc__': None}
# # <class '__main__.Foo'>
# # <class '__main__.FFo'>
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 24、自定义元类引入,__call__ 方法介绍
# # # 实例运加括号的时候,即实例 f1() 时候,会触发所属的类中的 __call__方法
# ------------------------------------------------------------
'''
#
# class Foo:
# def __call__(self, *args, **kwargs):
# print("我是__call__,我执行了!!")
#
# f1 = Foo()
# print("f1()")
#
# f1() # f1的类Foo 下的__call__
#
# print("Foo()")
# Foo()
# print( Foo() )
#
# # D:\Anaconda3\python.exe D:/C_cache/py/day27_MianXiangDuiXiangJinJie/day27_MianXiangDuiXiangJinJie.py
# # 我是__call__,我执行了!!
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 24.1、自定义元类引入,__call__ 方法介绍
# # # 实例运加括号的时候,即实例 f1() 时候,会触发所属的类中的 __call__方法
# ------------------------------------------------------------
# '''
#
# class Foo:
# def __call__(self, *args, **kwargs):
# print("我是__call__,我执行了!!")
# print(args, kwargs)
#
# f1 = Foo()
#
# f1("11",22) # f1的类Foo 下的__call__
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 我是__call__,我执行了!!
# # ('11', 22) {}
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 25.1、自定义元类引入1,元类定义自己的元类type
# ------------------------------------------------------------
'''
#
# class MyType(type):
# def __init__(self, a, b,c):
# '''
#
# :param a: 类的名称, 这里是字符串 "Foo"
# :param b: () 继承的对象,与上面的type 对比的话,可以发现,使用type定义时候,
# 继承的是 object
# :param c: 类的属性字典,相当于 Foo.__dict__
# '''
# print("【元类执行了】")
# print("a: ", a)
# print("b: ", b)
# print("c: ", c)
#
#
# '''
# FFo 类定义自己的元类; 如果是 默认的 Foo(metaclass=type)相当于触发了 type('Foo', (object, ),{})
# 这里的Foo(metaclass=MyType) 就是 Mytype('Foo', (), Foo.__dict__)
#
# '''
# class Foo(metaclass=MyType):
# def __init__(self, name):
# self.name = name
#
# def test(self):
# print("FFo【test】")
#
#
# print("dict:",Foo.__dict__)
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【元类执行了】
# # a: Foo
# # b: ()
# # c: {'__module__': '__main__', '__qualname__': 'Foo', '__init__': <function Foo.__init__ at 0x00000000039EE840>, 'test': <function Foo.test at 0x00000000039EE8C8>}
# # dict: {'__module__': '__main__', '__init__': <function Foo.__init__ at 0x00000000039EE840>, 'test': <function Foo.test at 0x00000000039EE8C8>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 25.2、自定义元类引入2,元类定义自己的元类type
# ------------------------------------------------------------
''' # class MyType(type):
# def __init__(self, a, b,c):
# '''
# 注释: Foo类,在编译器进行预编译处理的时候,就会运行这个 __init__
# :param a: 类的名称, 这里是字符串 "Foo"
# :param b: () 继承的对象,与上面的type 对比的话,可以发现,使用type定义时候,
# 继承的是 object
# :param c: 类的属性字典,相当于 Foo.__dict__
# '''
# print("【元类执行了】")
# # print("a: ", a)
# # print("b: ", b)
# # print("c: ", c)
#
# def __call__(self, *args, **kwargs):
# print("【__call__】")
#
# '''
# FFo 类定义自己的元类; 如果是 默认的 Foo(metaclass=type)相当于触发了 type('Foo', (object, ),{})
# 这里的Foo(metaclass=MyType) 就是 Mytype('Foo', (), Foo.__dict__)
#
# '''
# class Foo(metaclass=MyType):
# def __init__(self, name):
# self.name = name
#
# def test(self):
# print("FFo【test】")
#
#
# print("dict:",Foo.__dict__)
# # 运行Foo() 会触发Foo对应元类中的【__call__】; 注意到,这个操作实际上,就是相当于在使用类 Foo 进行实例化
# Foo()
# # Foo实例化的时候,触发,类 Foo 的元类中的 _call__方法
# f1 = Foo("aaa")
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【元类执行了】
# # dict: {'__module__': '__main__', '__init__': <function Foo.__init__ at 0x00000000039EE8C8>, 'test': <function Foo.test at 0x00000000039EE950>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
# # 【__call__】
# # 【__call__】
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 25.3、自定义元类引入2( 实例传入的内容信息),自定义元类中的 __call__ 方法
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs):
# # # __call__ 接收着,我们使用 Foo类 进行实例化时候的信息
# ------------------------------------------------------------
'''
#
# class MyType(type):
# def __init__(self, a, b,c):
# '''
# 注释: Foo类,在编译器进行预编译处理的时候,就会运行这个 __init__
# :param a: 类的名称, 这里是字符串 "Foo"
# :param b: () 继承的对象,与上面的type 对比的话,可以发现,使用type定义时候,
# 继承的是 object
# :param c: 类的属性字典,相当于 Foo.__dict__
# '''
# print("【元类执行了】")
# print("a: ", a)
# print("b: ", b)
# print("c: ", c)
#
# def __call__(self, *args, **kwargs):
# '''
# 说明: 这个部分的内容,实际上,储存着我们使用类进行实例化时候,传入的实例化的内容信息
# self : 实例本身,这里传进来的是实例 Foo, 也叫 类Foo
# :param args: 接收 在 Foo进行实例化时候的内容信息
# :param kwargs: 接收 在 Foo进行实例化时候的内容信息
# :return:
# '''
# print("【__call__】")
# print("self: ", self)
# print("args: ", args)
# print("kwargs: ", kwargs)
# print("分割线__call__".center(150, "-"))
#
# '''
# FFo 类定义自己的元类; 如果是 默认的 Foo(metaclass=type)相当于触发了 type('Foo', (object, ),{})
# 这里的Foo(metaclass=MyType) 就是 Mytype('Foo', (), Foo.__dict__)
#
# '''
# class Foo(metaclass=MyType):
# def __init__(self, name):
# self.name = name
#
# def test(self):
# print("FFo【test】")
#
#
# print("dict:",Foo.__dict__)
# # 运行Foo() 会触发Foo对应元类中的【__call__】; 注意到,这个操作实际上,就是相当于在使用类 Foo 进行实例化
# Foo()
# # Foo实例化的时候,触发,类 Foo 的元类中的 _call__方法
# f1 = Foo("aaa")
# f2 = Foo("f2在线", name="我是谁", age= "多少岁了", height=6.66)
#
# # print( f2.name) # 报错,因为在 Foo类 的元类 __call__ 中,只是对该实例的内容进行接收,而没有储存着
# #
# #
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【元类执行了】
# # dict: {'__module__': '__main__', '__init__': <function Foo.__init__ at 0x00000000039EE8C8>, 'test': <function Foo.test at 0x00000000039EE950>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
# # 【__call__】
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 25.3、自定义元类实现,自定义元类中的 __call__ 方法
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs): # ------------------------------------------------------------
'''
#
# class MyType(type):
# def __init__(self, a, b,c):
# '''
# 注释: 1、Foo类,在编译器进行预编译处理的时候,就会运行这个 __init__
# 2、 这个是默认传入4个参数的,其中self是自动传入的,关于self,self是在使用类进行
# 实例化的时候,会自动传入的参数
#
# self: 实例本身,这里传进来的是实例 Foo, 也叫 类Foo
# :param a: 类的名称, 这里是字符串 "Foo"
# :param b: () 继承的对象,与上面的type 对比的话,可以发现,使用type定义时候,
# 继承的是 object
# :param c: 类的属性字典,相当于 Foo.__dict__
# '''
# print("【元类执行了】")
# print("a: ", a)
# print("b: ", b)
# print("c: ", c)
#
# def __call__(self, *args, **kwargs):
# '''
# 说明: 这个部分的内容,实际上,储存着我们使用类进行实例化时候,传入的实例化的内容信息
# self : 实例本身,这里传进来的是实例 Foo, 也叫 类Foo
# :param args: 接收 在 Foo进行实例化时候的内容信息
# :param kwargs: 接收 在 Foo进行实例化时候的内容信息
# :return:
# '''
# print("【__call__】")
# print("args: ", args)
# print("kwargs: ", kwargs)
# # 相当于进行object.__new__( Foo ); 这里是产生实例d对象,新式类中的对象继承的是object
# obj = object.__new__(self)
# self.__init__(obj, *args, **kwargs)
# print("分割线__call__".center(150, "-"))
# return obj # 设置完成后,返回该对象
#
# '''
# FFo 类定义自己的元类; 如果是 默认的 Foo(metaclass=type)相当于触发了 type('Foo', (object, ),{})
# 这里的Foo(metaclass=MyType) 就是 Mytype('Foo', (), Foo.__dict__)
#
# '''
# class Foo(metaclass=MyType):
# def __init__(self, name):
# self.name = name
#
# def test(self):
# print("FFo【test】")
#
#
# print("dict:",Foo.__dict__)
# # 运行Foo() 会触发Foo对应元类中的【__call__】; 注意到,这个操作实际上,就是相当于在使用类 Foo 进行实例化
# # Foo() # 报错,因为这里需要传入一个类Foo 初始化的参数 name
#
# # Foo实例化的时候,触发,类 Foo 的元类中的 _call__方法 进行相关的属性设置
# f1 = Foo("aaa")
#
# print( "f1.name: ", f1.name)
#
# # f2 = Foo("f2在线", name="我是谁", age= "多少岁了", height=6.66) # 报错,类 Foo 中只是有一个默认的参数
#
#
#
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # 【元类执行了】
# # a: Foo
# # b: ()
# # c: {'__module__': '__main__', '__qualname__': 'Foo', '__init__': <function Foo.__init__ at 0x00000000039EE8C8>, 'test': <function Foo.test at 0x00000000039EE950>}
# # dict: {'__module__': '__main__', '__init__': <function Foo.__init__ at 0x00000000039EE8C8>, 'test': <function Foo.test at 0x00000000039EE950>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
# # 【__call__】
# # args: ('aaa',)
# # kwargs: {}
# # ---------------------------------------------------------------------分割线__call__----------------------------------------------------------------------
# # f1.name: aaa
# #
# # Process finished with exit code 0 '''
# ------------------------------------------------------------
# # 25.4、自定义元类实现(简洁版)
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs):
# ------------------------------------------------------------
'''
#
# class MyType(type):
# def __init__(self, a, b, c):
# '''
# 注释: Foo类,在编译器进行预编译处理的时候,就会运行这个 __init__
# self: 实例本身,这里传进来的是实例 Foo, 也叫 类Foo
# :param a: 类的名称, 这里是字符串 "Foo"
# :param b: () 继承的对象,与上面的type 对比的话,可以发现,使用type定义时候,
# 继承的是 object
# :param c: 类的属性字典,相当于 Foo.__dict__
# '''
# # print("【元类执行了】")
#
# def __call__(self, *args, **kwargs):
# '''
# 说明: 这个部分的内容,实际上,储存着我们使用类进行实例化时候,传入的实例化的内容信息
# self : 实例本身,这里传进来的是实例 Foo, 也叫 类Foo
# :param args: 接收 在 Foo进行实例化时候的内容信息
# :param kwargs: 接收 在 Foo进行实例化时候的内容信息
# :return:
# '''
# # print("【__call__】")
# # 相当于进行object.__new__( Foo ); 这里是产生实例d对象,新式类中的对象继承的是object
# obj = object.__new__(self)
# self.__init__(obj, *args, **kwargs)
# print("分割线__call__".center(150, "-"))
# return obj # 设置完成后,返回该对象
#
# '''
# FFo 类定义自己的元类; 如果是 默认的 Foo(metaclass=type)相当于触发了 type('Foo', (object, ),{})
# 这里的Foo(metaclass=MyType) 就是 Mytype('Foo', (), Foo.__dict__)
#
# '''
# class Foo(metaclass=MyType):
# def __init__(self, name):
# self.name = name
#
# def test(self):
# print("FFo【test】")
#
#
# # Foo实例化的时候,触发,类 Foo 的元类中的 _call__方法 进行相关的属性设置
# f1 = Foo("aaa")
#
# print( "f1.name: ", f1.name)
#
# # D:\Anaconda3\python.exe D:/C_cache/py/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi/Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi.py
# # ---------------------------------------------------------------------分割线__call__----------------------------------------------------------------------
# # f1.name: aaa
# #
# # Process finished with exit code 0

  


#!/usr/bin/env python
# -*- coding:utf-8 -*-
# ------------------------------------------------------------
#
# 参考资料:(未有转载)
# 面向对象进阶 - linhaifeng - 博客园
# https://www.cnblogs.com/linhaifeng/articles/6204014.html#_label12
#
# python之函数介绍及使用 - 病毒尖er - 博客园
# http://www.cnblogs.com/leguan1314/articles/6116928.html
#
# 元类metaclass - linhaifeng - 博客园
# http://www.cnblogs.com/linhaifeng/articles/8029564.html
#
# ------------------------------------------------------------
# ******************** day28-描述符应用与类的装饰器 *******************
# ******************** day28-描述符应用与类的装饰器 *******************
# =====>>>>>>内容概览
# =====>>>>>>内容概览
# Day28_MiaoShuFuYingYong_LeiDeZhuangShiQi

# ------------------------------------------------------------
# # 1、总结:
# # # hasattr, getattr, setattr;;  getitem, setitem, delitem;; set, get, delete;; __del__
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 2、 __enter__ 与 __exit__
# # # 这个使用的方法是类似于 with open() as 文件名;    
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 3、 __enter__ 与 __exit__ 之文件异常引入
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# # # 这个使用的方法是类似于 with open() as 文件名;    
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 3.1、 __enter__ 与 __exit__ 之文件异常引入1
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# # # 这个使用的方法是类似于 with open() as 文件名;    
# # # 其中,文件打开时,触发 __enter__ , 文件运行到结束的时候,会触发 __exit__
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 3.2、 __exit__ 中 exc_type, exc_val, exc_tb 之文件异常引入1
# # # __exit__ 中的 exc_type, exc_val, exc_tb 就是文件异常的信息内容
# # # __exit__ 中没有进行文件异常处理,一旦异常,后文件程序内容都不会运行的
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 3.3、 __exit__ 中 exc_type, exc_val, exc_tb 之文件异常
# # # __exit__ 中的 exc_type, exc_val, exc_tb 就是文件异常的信息内容
# # # __exit__ 中的返回值设置为True时,文件的异常会结束该文件内容的操作,但是对于
# # # 该操作外的操作信息不会有所影响,仍能够正常运行 
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 3.4、总结 __enter__ 与 __exit__ 
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 4、描述符的应用的引入
# # # test给定的参数中,如果是字符串或者整形数字就输出,否则留报错!显然,
# # # 下面的例子中,是不能够满足该要求的;  下面关于描述符的应用就是为了解决该问题
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 5、描述符中 __set__ 中的各个参数
# # # __set__中的各个参数:
# # # instance : 修饰的实例本身(下例中,就是实例p1)
# # # value    :实例中修饰的那个值(下例中,就是 alex)
# # # self     :描述符所在的类本身
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 6、描述符中 __get__ 中的各个参数
# # # __get__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# # # owner    :修饰的实例所属的类(下例中,是类People)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 6.1、描述符中 __get__ 中的各个参数
# # # __get__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# # # owner    :修饰的实例所属的类(下例中,是类People)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 6.2、描述符中 __delete__ 中的各个参数
# # # __delete__ 中的各个参数:
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 7、__set__  使用描述符给给定的实例中传入值  
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 8、__set__  使用描述符对给定的实例 获取对应的值  
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 9、使用描述符对给定的实例 的值的设定进行限制1
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 9.1、使用描述符对给定的实例 的值的设定进行限制2
# # # 对类进行修饰的时候,直接指定数值属性的  类型 ,如name 是str类型
# # # instance :修饰的实例本身(下例中,就是实例p1)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 10、装饰器的引入,修饰函数
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 11、装饰器修饰 类
# # # 类中的装饰器的运行的情况,是跟上面的函数的装饰器是有所区别的; 类中的是下运行类,之后再运行装饰器的运行
# # # 而函数中的,是先运行装饰器中的内容,之后再运行函数的内容
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 12、函数也是有字典的
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 12.1、给函数的字典添加属性
# # # 函数也可以像类一像添加属性,因为函数的本质就是类;python中的一切都是对像
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 13、使用装饰器给类中的字典添加属性
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 14、使用装饰器给类中的字典添加属性
# # # 只能在装饰器中内部给定值的情况
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 14.1、使用装饰器给类中的字典添加属性1
# # # 解决只能在装饰器中内部给定值的情况
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 15、装饰器的应用(与前面的序号10对比)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 16、property 的使用
# # # property() 函数的作用是在新式类中返回属性值。
# # # 下面例子中,(原)r1.area()-->>(现)r1.area 
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 17、property引入 , 类的装饰器
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 18、property装饰器初步 , 类的装饰器
# # # print(r1.area.func(r1))   实现了基本的装饰器功能
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 18.1、property装饰器初步之 __get__ , 类的装饰器
# # # 目标: print(r1.area.func(r1)) ==>> 等价于执行   print(r1.area) 
# # # __get__ 接受被修饰对象中的实例, 
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 18.2、property装饰器“实现”之 __get__ 返回运行的内容, 类的装饰器
# # # 目标(实现): print(r1.area.func(r1)) ==>> 等价于执行   print(r1.area) 
# # # __get__ 接受被修饰对象中的实例, 
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 18.3、property装饰器“实现” (简洁版)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 18.4、property装饰器“实现” (简洁版) 与 内置的property装饰器对比1
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 19、property装饰器,之类调用静态属性 对比
# # # “实现” (简洁版) 与 内置的property装饰器
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 19.1、property装饰器,之类调用静态属性,实现property的完整功能( 类无法调用静态属性)
# # # “实现” (简洁版) 与 内置的property装饰器
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 20、__name__获取函数的名字
# # # 用来获取运行的模块的名字,  或者对应的对象的名字(类是获取不到名字的)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 21、property装饰器,之类调用静态属性,实现property的完整功能
# # # “实现” (简洁版) 与 内置的property装饰器
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 21.1、元类的引入
# # # python中一切皆为对象。类的本身也是一个对象,由 type 产生
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 22、type 元类来产生 类

# # # FFo = type("FFo", (object,), {'x': 1})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo",      类名
# # # 位置2:(object,),  对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3:{'x': 1},    类的属性字典
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 22.1、type 元类来产生 类
# # # 给类中添加类的初始化属数,类的数值属性, 类的函数属性

# # # FFo = type("FFo", (object,), {'x':1, '__init__':__init__, 'test':test})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo",      类名
# # # 位置2:(object,),  对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3: {'x':1, '__init__':__init__, 'test':test},    类的属性字典
# # # 'x':1  相当于在类中定义数值属性   x = 1
# # # '__init__':__init__  相当于在类中定义类初化始的函数属性   def __init__(self)
# # # 'test':test          相当于在类中定义类的函数属性   def test(self)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 22.2、type 元类产生的类进行  实例化
# # # 给类中添加类的初始化属数,类的数值属性, 类的函数属性

# # # FFo = type("FFo", (object,), {'x':1, '__init__':__init__, 'test':test})
# # # type(位置1, 位置2, 位置3)
# # # 位置1:"FFo",      类名
# # # 位置2:(object,),  对象, 新式类的对象是 object, python3中所有的类都是新式类
# # # 位置3: {'x':1, '__init__':__init__, 'test':test},    类的属性字典
# # # 'x':1  相当于在类中定义数值属性   x = 1
# # # '__init__':__init__  相当于在类中定义类初化始的函数属性   def __init__(self)
# # # 'test':test          相当于在类中定义类的函数属性   def test(self)
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 22.3、类的产生总结
# # # 类的产生有两种方式,1、通过 class来定义类;       2、通过type来产生类
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 23、自定义元类引入,元类定义自己的元类type
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 24、自定义元类引入,__call__ 方法介绍
# # # 实例运加括号的时候,即实例 f1() 时候,会触发所属的类中的 __call__方法
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 24.1、自定义元类引入,__call__ 方法介绍
# # # 实例运加括号的时候,即实例 f1() 时候,会触发所属的类中的 __call__方法
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 25.1、自定义元类引入1,元类定义自己的元类type
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 25.2、自定义元类引入2,元类定义自己的元类type
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 25.3、自定义元类引入2( 实例传入的内容信息),自定义元类中的 __call__ 方法
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs):
# # # __call__ 接收着,我们使用 Foo类 进行实例化时候的信息
# ------------------------------------------------------------

# ------------------------------------------------------------
# # 25.3、自定义元类实现,自定义元类中的 __call__ 方法
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs):

# ------------------------------------------------------------

# ------------------------------------------------------------
# # 25.4、自定义元类实现(简洁版)
# # # 这里需要关注的是 __call__下的参数的内容==》》 def __call__(self, *args, **kwargs):
# ------------------------------------------------------------

# ------------------------------------------------分割线-------------------------------------------------
# ------------------------------------------------分割线-------------------------------------------------
# ------------------------------------------------分割线-------------------------------------------------

day28-描述符应用与类的装饰器的更多相关文章

  1. python描述符(descriptor)、属性(property)、函数(类)装饰器(decorator )原理实例详解

     1.前言 Python的描述符是接触到Python核心编程中一个比较难以理解的内容,自己在学习的过程中也遇到过很多的疑惑,通过google和阅读源码,现将自己的理解和心得记录下来,也为正在为了该问题 ...

  2. 11.python描述符---类的装饰器---@property

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

  3. Python全栈day28(类的装饰器)

    类是一个对象也可以像函数一样加装饰器 类的装饰器.py def deco(obj): print('======',obj) obj.x=1 obj.y=2 obj.z=3 return obj # ...

  4. Python之路(第二十八篇) 面向对象进阶:类的装饰器、元类

    一.类的装饰器 类作为一个对象,也可以被装饰. 例子 def wrap(obj): print("装饰器-----") obj.x = 1 obj.y = 3 obj.z = 5 ...

  5. python 类的装饰器

    我们知道,在不改变原有代码的基础上,我们可以使用装饰器为函数添加新的功能.同理,一切皆对象,我们也可以使用装饰器为类添加类属性.what? def deco(obj): obj.x = 1 obj.y ...

  6. python使用类作为装饰器

    1.普通就是一个函数作为装饰器,也可以用类名作为装饰器. 因为类和函数都是callable的,都可以使用括号来调用运行他. 2.上上篇的缓存一段时间的还是函数作为装饰器,类只是充当了比模块更下一级的命 ...

  7. day8_类的装饰器和反射

    """ 类的装饰器: @property 当类的函数属性声明 @property后, 函数属性不需要加括号 即可调用 @staticmethod 当类的函数属性声明 @s ...

  8. Python学习第十九课——类的装饰器

    类的装饰器 # def deco(func): # print('==========') # return func # # # @deco #test=deco(test) # # def tes ...

  9. 第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法

    第7.18节 案例详解:Python类中装饰器@staticmethod定义的静态方法 上节介绍了Python中类的静态方法,本节将结合案例详细说明相关内容. 一.    案例说明 本节定义了类Sta ...

随机推荐

  1. SELinux导致PHP连接MySQL异常Can't connect to MySQL server的解决方法

    原文摘自:http://www.jb51.net/article/52581.htm 这篇文章主要介绍了SELinux导致PHP连接MySQL异常Can't connect to MySQL serv ...

  2. linux中CentOS、Ubuntu、Debian三个版本系统 差别

    Linux有非常多的发行版本,从性质上划分,大体分为由商业公司维护的商业版本与由开源社区维护的免费发行版本. 商业版本以Redhat为代表,开源社区版本则以debian为代表.这些版本各有不同的特点, ...

  3. Delphi实现提取可执行文件内部所有图标

    本实例实现的功能是能够从用户选择的可执行文件(后缀名为exe)中提取所有图标并且显示在窗体上. 在窗体中添加TImage 组件.TOpenDialog组件和TButton组件,TImage组件充当显示 ...

  4. hihoCoder [Offer收割]编程练习赛3 D子矩阵求和

    子矩阵求和 http://hihocoder.com/discuss/question/3005 声明一下: n是和x一起的,m是和y一起的 x是横着的,y是纵着的,x往右为正,y往下为正 (非常反常 ...

  5. ElasticSearch Roaring bitmap 和跳表联合查询

    ElasticSearch Roaring map 先把所有数按65535划分, 划分方法就是求商和余数,商代表数字最终在哪一块,余数代表最终在块内的数字 比如 1, 65536, 65537, 13 ...

  6. Maven 打包jar清单

    <project> ... <build> <plugins> <plugin> <groupId>org.apache.maven.plu ...

  7. git分布式版本控制系统权威指南学习笔记(二):git add暂存区的三个状态以及暂存区的理解

    文章目录 不经过git add(到暂存区),能直接进行commit吗? 举个

  8. arttemplate 后台返回的数据格式问题

    1. 2.JSON.parse() 方法用于将一个 JSON 字符串转换为对象. $("body").on("click","#analyze&quo ...

  9. Linux内核代码布局

    上文参考:http://www.cnblogs.com/long123king/p/3545991.html 先分析一下linker script的语法. #ifdef CONFIG_X86_32#d ...

  10. 20140806 交换两个数 extern “C”用法

    1.交换两个数 方法1.a+b有可能越界 a=a+b; b=a-b; a=a-b; 方法二.不会越界 a=a^b b=a^b; a=a^b;   2.extern "C"用法 ( ...