day26-多态、封装、反射
阅读原文时间:2023年07月10日阅读:1

#!/usr/bin/env python

-*- coding:utf-8 -*-

------------------------------------------------------------

参考资料:

面向对象编程初步 - tonador - 博客园

https://www.cnblogs.com/yujianbao/articles/6223482.html

Python成长之路【第九篇】:Python基础之面向对象 - Mr_Albert - 博客园

https://www.cnblogs.com/albert0924/p/8921709.html

Python 学习 --day-16 - UMRzg - 博客园

http://www.cnblogs.com/qinzheg/articles/9394420.html

Python之路,Day6 - 面向对象学习 - 金角大王 - 博客园

http://www.cnblogs.com/alex3714/articles/5188179.html

面向对象进阶 - linhaifeng - 博客园

https://www.cnblogs.com/linhaifeng/articles/6204014.html

------------------------------------------------------------

******************** day26-多态、封装、反射 *******************

******************** day26-多态、封装、反射 *******************

=====>>>>>>内容概览

=====>>>>>>内容概览

------------------------------------------------------------

# 1、多态的概念

# # 多态:

# # 多态的概念指出了对象如何通过他们共同的属性和动作来操作及访问,而不需要考虑他们具体的类

# # 多态表明了动态(又名,运行时)绑定的存在

# # 类的继承有两层意义:1、改变 2、扩展

# # 多态就是类的这两层意义的一个具体的实现机制,即,调用不同的类实例化得对象下的相同的方法,实现的过程不一样

# # Python中的标准类型就是多态概念的一个很好示范

------------------------------------------------------------

------------------------------------------------------------

# 2、多态的引入len()

# # len()中,可以计算的长度有字符串、 列表、 元组等,但是他们是不属于一个类的

------------------------------------------------------------

------------------------------------------------------------

# 3、多态的引入len()

# # len()中,可以计算的长度有字符串、 列表、 元组等,但是他们是不属于一个类的

------------------------------------------------------------

------------------------------------------------------------

# 3.1、多态的实现1

------------------------------------------------------------

------------------------------------------------------------

# 3.2、多态的实现2(与前面的序列2中的len对比)

------------------------------------------------------------

------------------------------------------------------------

# 4、封装的作用

# # 封装的目的就是为了明确区分内部和外部,

# # 那么如何实现封的效果呢?

# # 第一个层面的封装:类就是袋子,这本身就是一种封装

# # 例:略

# # 第二个层面的封装:类中定义私有的,只在类的内部使用,外部无法访问

# # 例:4.1

------------------------------------------------------------

------------------------------------------------------------

# 4.1、封装之类中的“_”

# # 变量名字前边加一个下划线“_”就代表了只在内部使用,外部不可调用

# # 需要主要的是,这个是一种约定!

------------------------------------------------------------

------------------------------------------------------------

# 4.2、封装之类中的“__”

# # 变量名字A前边加一个下划线“__”就代表了只在内部使用,外部不可调用

# # 需要主要的是,这个是一种约定! 另外,在外部调用的时候,类P会对名字A进行重命名,在名字A的前面你加入

# # _类P的名字

# # 调用;内部,名字A; 外部,__类P的名字接上名字A

------------------------------------------------------------

------------------------------------------------------------

# 4.3、外部调用被封装的类中属性

# # 当类中的属性被封装起来的时候,外部只能通过在类的内部定一个获取该信息的函数

------------------------------------------------------------

------------------------------------------------------------

# 4.4、封装示范

# # 当类中的属性被封装起来的时候,外部只能通过在类的内部定一个获取该信息的函数

------------------------------------------------------------

------------------------------------------------------------

# 4.5、封装总结

# # 封装的目的是为了区分内外的逻辑,在进行编写程序的时候,如果不确定类中的属性是否需要隐藏起来,

# # 应当选择的是不封装

------------------------------------------------------------

------------------------------------------------------------

# 5、反射,

# # 主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)

------------------------------------------------------------

------------------------------------------------------------

# 6、hasattr,

# # 检测是否含有某属性

------------------------------------------------------------

------------------------------------------------------------

# 7、getattr, 获取属性

# # 检测是否含有某属性, 扣如果是数值属性的话,会返回内容; 如果是函数属性的话,会返回函数地址

------------------------------------------------------------

------------------------------------------------------------

# 7.1、getattr, 获取属性并运行

# # 检测是否含有某属性, 扣如果是数值属性的话,会返回内容; 如果是函数属性的话,会返回函数地址

------------------------------------------------------------

------------------------------------------------------------

# 8、setattr设置属性

# # 设置属性

------------------------------------------------------------

------------------------------------------------------------

# 8.1、setattr设置属性为函数

# # 设置属性为函数

------------------------------------------------------------

------------------------------------------------------------

# 9、delattr 删除属性

# # 删除属性,只能删除数值属性,不能删除“函数属性”

------------------------------------------------------------

------------------------------------------------------------

# 9.1、反射的应用,——部分功能没有完善

# # 假设如下场景,A,B同时开发一个程序,A开发 ftp_client 的功能还没有完善,但是B开发

# # ftp_user 需要使用ftp_client的功能,此时这个功能就派上用场了

------------------------------------------------------------

------------------------------------------------------------

# 9.2、反射的应用,——部分功能已经完善

# # 假设如下场景,A,B同时开发一个程序,A开发 ftp_client 的功能还没有完善,但是B开发

# # ftp_user 需要使用ftp_client的功能,此时这个功能就派上用场了

------------------------------------------------------------

------------------------------------------------------------

# 10、__import__('m1.t') 动态导入模块

------------------------------------------------------------

------------------------------------------------------------

# 11、__import__('m1.t') 动态导入模块的内部函数

------------------------------------------------------------

------------------------------------------------------------

# 12、__import__('m1.t') 动态导入模块的内部函数

------------------------------------------------------------

------------------------------------------------------------

# 13、__getattr__

# # 类中的__getattr__,查找属性不存在的时候,就会触发!

------------------------------------------------------------

------------------------------------------------------------

# 14、__delattr__删除操作

# # 删除的操作,相当于重写了类中的delattr。

# # 下列演示中,重写后的__delattr__中只是触发了__delattr__,没有触发删除指定的内容

------------------------------------------------------------

------------------------------------------------------------

# 15、__setattr__设置属性操作之不允许添加

# # _setattr__添加/修改属性会触发它的执行

------------------------------------------------------------

------------------------------------------------------------

# 15.1、__setattr__设置属性操作之添加内容

# # _setattr__添加/修改属性会触发它的执行

------------------------------------------------------------

------------------------------------------------------------

# 16、内置属性查询

# # 内置属性查询dir是将所有的列出来

------------------------------------------------------------

------------------------------------------------------------

# 17、__getattr__, __delattr__, __setattr__的一些应用

------------------------------------------------------------

------------------------------------------------------------

# 18、继承的方式完成包装,__setattr__,添加属性指定,以及删除函数的原型

# # 添加属性的本质就是操作“属性字典”, f1.age = 333 等价于 self.__dict__[key] = value

# # 等价内容: f1 == self; age == key; value == 333

# # 下列中,只是允许字符串类型的添加

------------------------------------------------------------

------------------------------------------------------------

# 19、继承的方式完成包装,__delattr__,以及删除函数的原型

# # 删除属性的本质就是操作“属性字典”, del f1.sex 等价于 self.__dict__.pop(item)

# # 等价内容: f1 == self; sex == item;

# #

------------------------------------------------------------

------------------------------------------------------------

# 20、list类继承与函数属性添加

------------------------------------------------------------

------------------------------------------------------------

# 21、list类继承与函数属性append修改

------------------------------------------------------------

------------------------------------------------------------

# 21.1、list类继承与函数属性append修改,super()

------------------------------------------------------------

------------------------------------------------------------

# 22、授权的概念:

# # 授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法

# # 可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功

# # 能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

# #

# # 实现授权的关键点就是覆盖__getattr__方法

------------------------------------------------------------

------------------------------------------------------------

# 23、授权__getattr__

------------------------------------------------------------


_**
# ------------------------------------------------分割线-------------------------------------------------

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

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

**_


# 01 02 是复习内容,就不写入了

01 02 是复习内容,就不写入了

03 多态

03 多态

'''

------------------------------------------------------------

# 1、多态的概念

# # 多态:

# # 多态的概念指出了对象如何通过他们共同的属性和动作来操作及访问,而不需要考虑他们具体的类

# # 多态表明了动态(又名,运行时)绑定的存在

# # 类的继承有两层意义:1、改变 2、扩展

# # 多态就是类的这两层意义的一个具体的实现机制,即,调用不同的类实例化得对象下的相同的方法,实现的过程不一样

# # Python中的标准类型就是多态概念的一个很好示范

------------------------------------------------------------

'''

'''

------------------------------------------------------------

# 2、多态的引入len()

# # len()中,可以计算的长度有字符串、 列表、 元组等,但是他们是不属于一个类的

------------------------------------------------------------

'''

a = "afdss"

b = 1111

c = [11, 2, 3, 4, b, a]

d = (1111, 2222, 3333, a, b, c)

print(a, len(a), a.__len__())

print(c, len(c), c.__len__())

print(d, len(d), d.__len__())

D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

afdss 5 5

[11, 2, 3, 4, 1111, 'afdss'] 6 6

(1111, 2222, 3333, 'afdss', 1111, [11, 2, 3, 4, 1111, 'afdss']) 6 6

Process finished with exit code 0

'''

------------------------------------------------------------

# 3、多态的引入len()

# # len()中,可以计算的长度有字符串、 列表、 元组等,但是他们是不属于一个类的

------------------------------------------------------------

'''

a = "afdss"

b = 1111

c = [11, 2, 3, 4, b, a]

d = (1111, 2222, 3333, a, b, c)

print(a, len(a), a.__len__())

print(c, len(c), c.__len__())

print(d, len(d), d.__len__())

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# afdss 5 5

# [11, 2, 3, 4, 1111, 'afdss'] 6 6

# (1111, 2222, 3333, 'afdss', 1111, [11, 2, 3, 4, 1111, 'afdss']) 6 6

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 3.1、多态的实现1

------------------------------------------------------------

'''

class H2O:

def __init__(self, name, temperature):

self.name = name

self.temperature = temperature

def turn_ice(self):

if self.temperature < 0:

print("[%s]温度太低,结冰了" %self.name)

elif self.temperature > 0 and self.temperature <100:

print(" [%s]液化成水" %self.name)

elif self.temperature >100:

print(" [%s]温度太高变成了水蒸气" %self.name)

class Water(H2O):

pass

class Ice(H2O):

pass

class Stream(H2O):

pass

w1 = Water("水", 25)

i1 = Ice("冫水 ",-20)

s1 = Stream("蒸汽", 225)

w1.turn_ice()

i1.turn_ice()

s1.turn_ice()

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# [水]液化成水

# [冫水 ]温度太低,结冰了

# [蒸汽]温度太高变成了水蒸气

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 3.2、多态的实现2(与前面的序列2中的len对比)

------------------------------------------------------------

'''

class H2O:

def __init__(self, name, temperature):

self.name = name

self.temperature = temperature

def turn_ice(self):

if self.temperature < 0:

print("[%s]温度太低,结冰了" %self.name)

elif self.temperature > 0 and self.temperature <100:

print(" [%s]液化成水" %self.name)

elif self.temperature >100:

print(" [%s]温度太高变成了水蒸气" %self.name)

class Water(H2O):

pass

class Ice(H2O):

pass

class Stream(H2O):

pass

w1 = Water("水", 25)

i1 = Ice("冫水 ",-20)

s1 = Stream("蒸汽", 225)

def turn(obj):

obj.turn_ice()

turn(w1) # ---> w1.turn_ice()

turn(i1) # ---> i1.turn_ice()

turn(s1) # ---> s1.turn_ice()

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# [水]液化成水

# [冫水 ]温度太低,结冰了

# [蒸汽]温度太高变成了水蒸气

#

# Process finished with exit code 0

#

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

04 封装

04 封装

#

'''

------------------------------------------------------------

# 4、封装的作用

# # 封装的目的就是为了明确区分内部和外部,

# # 那么如何实现封的效果呢?

# # 第一个层面的封装:类就是袋子,这本身就是一种封装

# # 例:略

# # 第二个层面的封装:类中定义私有的,只在类的内部使用,外部无法访问

# # 例:4.1

------------------------------------------------------------

'''

'''

------------------------------------------------------------

# 4.1、封装之类中的“_”

# # 变量名字前边加一个下划线“_”就代表了只在内部使用,外部不可调用

# # 需要主要的是,这个是一种约定!

------------------------------------------------------------

'''

class People:

star = 'earth'

_capital1 = '==北京=='

def __init__(self, id, name, age,salary):

self.id = id

self.name = name

self.age = age

self.salary = salary

def get_info(self):

print("类内部的get_info函数!-----START------")

print("star = %s, _capital1 = %s" %(self.star, self._capital1)) # _capital1可以直接调用

print("类内部的get_info函数!-------END------")

print(People.__dict__)

p1 = People('666666', 'alex', '18', 88888)

print(p1.star )

print(p1._capital1 )

p1.get_info()

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# {'__module__': '__main__', 'star': 'earth', '_capital1': '==北京==', '__init__': , 'get_info': , '__dict__': , '__weakref__': , '__doc__': None}

# earth

# ==北京==

# 类内部的get_info函数!-----START------

# star = earth, _capital1 = ==北京==

# 类内部的get_info函数!-------END------

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 4.2、封装之类中的“__”

# # 变量名字A前边加一个下划线“__”就代表了只在内部使用,外部不可调用

# # 需要主要的是,这个是一种约定! 另外,在外部调用的时候,类P会对名字A进行重命名,在名字A的前面你加入

# # _类P的名字

# # 调用;内部,名字A; 外部,__类P的名字接上名字A

------------------------------------------------------------

'''

class People:

star = 'earth'

_capital1 = '==北京=='

__capital2 = '==北京=='

def __init__(self, id, name, age,salary):

self._id = id

self.__name = name

self.age = age

self.salary = salary

def get_info(self):

print("类内部的get_info函数!-----START------")

# _capital1,__capital2可以直接调用

print("star = %s, _capital1 = %s, self.__capital2 = %s" \

%(self.star, self._capital1, self.__capital2))

print("self._id = %s, self.__name = %s, self.age = %s"\

%(self._id, self.__name, self.age))

print("类内部的get_info函数!-------END------")

print("实例化前:\n", " People.__dict__: ", People.__dict__)

p1 = People('666666', 'alex', '18', 88888)

print("实例化后:\n", " People.__dict__:",People.__dict__)

print("p1.__dict__: ", p1.__dict__)

print(p1.star )

print(p1._capital1 )

# python中自动会对类中的__capital2进行重命,在他们的前面加入__People

print(p1._People__capital2 )

print("p1._id = %s, p1._People__name = %s, p1.age = %s" \

% (p1._id, p1._People__name, p1.age))

print("分割线".center(100,"-"))

p1.get_info()

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# 实例化前:

# People.__dict__: {'__module__': '__main__', 'star': 'earth', '_capital1': '==北京==', '_People__capital2': '==北京==', '__init__': , 'get_info': , '__dict__': , '__weakref__': , '__doc__': None}

# 实例化后:

# People.__dict__: {'__module__': '__main__', 'star': 'earth', '_capital1': '==北京==', '_People__capital2': '==北京==', '__init__': , 'get_info': , '__dict__': , '__weakref__': , '__doc__': None}

# p1.__dict__: {'_id': '666666', '_People__name': 'alex', 'age': '18', 'salary': 88888}

# earth

# ==北京==

# ==北京==

# p1._id = 666666, p1._People__name = alex, p1.age = 18

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

# 类内部的get_info函数!-----START------

# star = earth, _capital1 = ==北京==, self.__capital2 = ==北京==

# self._id = 666666, self.__name = alex, self.age = 18

# 类内部的get_info函数!-------END------

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 4.3、外部调用被封装的类中属性

# # 当类中的属性被封装起来的时候,外部只能通过在类的内部定一个获取该信息的函数

------------------------------------------------------------

'''

class People:

star = 'earth'

_capital1 = '**北京**'

__capital2 = '**北京**'

def __init__(self, id, name, age,salary):

self._id = id

self.__name = name

self.age = age

self.salary = salary

def get_capital1(self):

print("这个是:_capital1 = %s" %self._capital1)

def get_capital2(self):

print("这个是:__capital2 = %s"% self.__capital2)

def get_IiniId(self):

print("这个是:_id = %s"% self._id)

def get_InitName(self):

print("这个是:__name = %s"% self.__name)

print("实例化前:\n", " People.__dict__: ", People.__dict__)

p1 = People('666666', 'alex', '18', 88888)

print("实例化后:\n", " People.__dict__:",People.__dict__)

print("p1.__dict__: ", p1.__dict__)

print("分割线".center(100,"-"))

p1.get_capital1()

p1.get_capital2()

p1.get_IiniId()

p1.get_InitName()

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# 实例化前:

# People.__dict__: {'__module__': '__main__', 'star': 'earth', '_capital1': '**北京**', '_People__capital2': '**北京**', '__init__': , 'get_capital1': , 'get_capital2': , 'get_IiniId': , 'get_InitName': , '__dict__': , '__weakref__': , '__doc__': None}

# 实例化后:

# People.__dict__: {'__module__': '__main__', 'star': 'earth', '_capital1': '**北京**', '_People__capital2': '**北京**', '__init__': , 'get_capital1': , 'get_capital2': , 'get_IiniId': , 'get_InitName': , '__dict__': , '__weakref__': , '__doc__': None}

# p1.__dict__: {'_id': '666666', '_People__name': 'alex', 'age': '18', 'salary': 88888}

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

# 这个是:_capital1 = **北京**

# 这个是:__capital2 = **北京**

# 这个是:_id = 666666

# 这个是:__name = alex

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 4.4、封装示范

# # 当类中的属性被封装起来的时候,外部只能通过在类的内部定一个获取该信息的函数

------------------------------------------------------------

'''

class Room:

def __init__(self, name, owner, width, length, high):

self.name = name

self.owner= owner

self.__width = width

self.__length = length

self.__high = high

# 求房子的面积

def tell_area(self):

return self.__length*self.__width

def tell_high(self):

return self.__high

r1 = Room("卫生间", "tom", 100, 100, 666)

# 封装了之后, 想要求面积,只能通过在原有的类中进行定义,并且返回元素

print(r1.tell_area())

print("它的高是:%s"%r1.tell_high())

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# 10000

# 它的高是:666

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 4.5、封装总结

# # 封装的目的是为了区分内外的逻辑,在进行编写程序的时候,如果不确定类中的属性是否需要隐藏起来,

# # 应当选择的是不封装

------------------------------------------------------------

'''

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

07 反射

07 反射

面向对象进阶 - linhaifeng - 博客园

https://www.cnblogs.com/linhaifeng/articles/6204014.html

'''

------------------------------------------------------------

# 5、反射,

# # 主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)

------------------------------------------------------------

'''

'''

------------------------------------------------------------

# 6、hasattr,

# # 检测是否含有某属性

------------------------------------------------------------

'''

class BlackMedium:

feature = 'Ugly'

def __init__(self, name, addr):

self.name = name

self.addr = addr

def sell_house(self):

print("【%s】 正在卖房子!!" %self.name)

def rent_house(self):

print("【%s】 正在租房子"%self.name)

# 实例化

b1 = BlackMedium("中介", "城中村")

# 检测是否含有某属性

print( hasattr(b1, 'name') )

print( hasattr(b1, 'sell_house') )

print( hasattr(b1, 'rent_house') )

print( hasattr(b1, 'rent=====>>') )

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# True

# True

# True

# False

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 7、getattr, 获取属性

# # 检测是否含有某属性, 扣如果是数值属性的话,会返回内容; 如果是函数属性的话,会返回函数地址

# # 不存在的话会报错

------------------------------------------------------------

'''

class BlackMedium:

feature = 'Ugly'

def __init__(self, name, addr):

self.name = name

self.addr = addr

def sell_house(self):

print("【%s】 正在卖房子!!" %self.name)

def rent_house(self):

print("【%s】 正在租房子"%self.name)

# 实例化

b1 = BlackMedium("中介", "城中村")

# #获取属性

print( getattr(b1, 'name') )

print( getattr(b1, 'sell_house') )

print( getattr(b1, 'rent_house') )

# print( getattr(b1, 'rent=====>>') ) # 报错,没有指定不在在的情况的处理

print( getattr(b1, 'rent=====>>', "==>>>这种属性不存在"))

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# 中介

# >

# >

# ==>>>这种属性不存在

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 7.1、getattr, 获取属性并运行

# # 检测是否含有某属性, 扣如果是数值属性的话,会返回内容; 如果是函数属性的话,会返回函数地址

------------------------------------------------------------

'''

class BlackMedium:

feature = 'Ugly'

def __init__(self, name, addr):

self.name = name

self.addr = addr

def sell_house(self):

print("【%s】 正在卖房子!!" %self.name)

def rent_house(self):

print("【%s】 正在租房子"%self.name)

# 实例化

b1 = BlackMedium("中介", "城中村")

# 获取属性

name = getattr(b1, 'name')

sell = getattr(b1, 'sell_house')

rent = getattr(b1, 'rent_house')

# 使用获取到的属性

print(name)

sell()

rent()

D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

中介

【中介】 正在卖房子!!

【中介】 正在租房子

Process finished with exit code 0

'''

------------------------------------------------------------

# 8、setattr设置属性

# # 设置属性

------------------------------------------------------------

'''

class BlackMedium:

feature = 'Ugly'

def __init__(self, name, addr):

self.name = name

self.addr = addr

def sell_house(self):

print("【%s】 正在卖房子!!" %self.name)

def rent_house(self):

print("【%s】 正在租房子"%self.name)

# 实例化

b1 = BlackMedium("中介", "城中村")

print(b1.__dict__)

# 设置属性

# 不用setattr

b1.clothes = "New!"

# 用setattr

setattr( b1, 'clothes1', "NewOne" )

print(b1.__dict__)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# {'name': '中介', 'addr': '城中村'}

# {'name': '中介', 'addr': '城中村', 'clothes': 'New!', 'clothes1': 'NewOne'}

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 8.1、setattr设置属性为函数

# # 设置属性为函数

------------------------------------------------------------

'''

class BlackMedium:

feature = 'Ugly'

def __init__(self, name, addr):

self.name = name

self.addr = addr

def sell_house(self):

print("【%s】 正在卖房子!!" %self.name)

def rent_house(self):

print("【%s】 正在租房子"%self.name)

# 实例化

b1 = BlackMedium("中介", "城中村")

print("b1.__dict__: ", b1.__dict__)

print("BlackMedium.__dict__:", BlackMedium.__dict__)

print("分割线".center(100,"-"))

# 设置属性

# 不用setattr

def func_add(x, y ):

return x+y

b1.func_add= func_add # 注意。这里给的是地址

# 用setattr

setattr( b1, 'func', lambda x :x+1 )

setattr( b1, 'func1', lambda self :self+100 ) # 这里的self与上面的x没有区别,都是参数

print("b1.__dict__: ", b1.__dict__)

print("BlackMedium.__dict__:", BlackMedium.__dict__)

print("分割线".center(100,"-"))

print( b1.func_add(10, 10 ) )

print("分割线".center(100,"-"))

print(b1.func)

print(b1.func(9))

print(b1.func(10))

print(b1.func1(10))

print("分割线".center(100,"-"))

print("b1.__dict__: ", b1.__dict__)

print("BlackMedium.__dict__:", BlackMedium.__dict__)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# b1.__dict__: {'name': '中介', 'addr': '城中村'}

# BlackMedium.__dict__: {'__module__': '__main__', 'feature': 'Ugly', '__init__': , 'sell_house': , 'rent_house': , '__dict__': , '__weakref__': , '__doc__': None}

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

# b1.__dict__: {'name': '中介', 'addr': '城中村', 'func_add': , 'func': at 0x00000000039EE8C8>, 'func1': at 0x00000000039EE950>}

# BlackMedium.__dict__: {'__module__': '__main__', 'feature': 'Ugly', '__init__': , 'sell_house': , 'rent_house': , '__dict__': , '__weakref__': , '__doc__': None}

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

# 20

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

# at 0x00000000039EE8C8>

# 10

# 11

# 110

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

# b1.__dict__: {'name': '中介', 'addr': '城中村', 'func_add': , 'func': at 0x00000000039EE8C8>, 'func1': at 0x00000000039EE950>}

# BlackMedium.__dict__: {'__module__': '__main__', 'feature': 'Ugly', '__init__': , 'sell_house': , 'rent_house': , '__dict__': , '__weakref__': , '__doc__': None}

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 9、delattr 删除属性

# # 删除属性,只能删除数值属性,不能删除“函数属性”

------------------------------------------------------------

'''

class BlackMedium:

feature = 'Ugly'

def __init__(self, name, addr):

self.name = name

self.addr = addr

def sell_house(self):

print("【%s】 正在卖房子!!" %self.name)

def rent_house(self):

print("【%s】 正在租房子"%self.name)

# 实例化

b1 = BlackMedium("中介", "城中村")

print("b1.__dict__: ", b1.__dict__)

print("BlackMedium.__dict__:", BlackMedium.__dict__)

print("分割线".center(100,"-"))

# 设置属性

# 不用setattr

b1.clothes = "New!"

# 用setattr

setattr( b1, 'clothes1', "NewOne" )

print(b1.__dict__)

print("分割线".center(100,"-"))

# 删除属性

del b1.clothes

# del b1.sell_house() # 报错,无法删除函数

# del b1.clothes99999999 # 报错,不存在

delattr(b1, 'clothes1')

# delattr(b1, 'clothes-----') # 报错,不存在

# delattr(b1, 'ren_house()') # 报错,不存在

print("b1.__dict__: ", b1.__dict__)

print("BlackMedium.__dict__:", BlackMedium.__dict__)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# b1.__dict__: {'name': '中介', 'addr': '城中村'}

# BlackMedium.__dict__: {'__module__': '__main__', 'feature': 'Ugly', '__init__': , 'sell_house': , 'rent_house': , '__dict__': , '__weakref__': , '__doc__': None}

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

# {'name': '中介', 'addr': '城中村', 'clothes': 'New!', 'clothes1': 'NewOne'}

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

# b1.__dict__: {'name': '中介', 'addr': '城中村'}

# BlackMedium.__dict__: {'__module__': '__main__', 'feature': 'Ugly', '__init__': , 'sell_house': , 'rent_house': , '__dict__': , '__weakref__': , '__doc__': None}

#

# Process finished with exit code 0

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

08 反射part2及动态导入模块

08 反射part2及动态导入模块

'''

------------------------------------------------------------

# 9.1、反射的应用,——部分功能没有完善

# # 假设如下场景,A,B同时开发一个程序,A开发 ftp_client 的功能还没有完善,但是B开发

# # ftp_user 需要使用ftp_client的功能,此时这个功能就派上用场了

ftp_client.py文件内容:

class FtpClient:
'ftp客户端,但是还没有实现具体的功能'
def __init__(self, addr):
print("正在连接服务器[ %s ]" %addr)
self.addr = addr

ftp_user.py文件内容:

from ftp_client import FtpClient
f1 = FtpClient("1.1.1.1")

f1.put()

if hasattr(f1, "put"):
func_get = getattr(f1,'put')
func_get()
else:
print("其他的逻辑")

------------------------------------------------------------

'''

from ftp_client import FtpClient

f1 = FtpClient("1.1.1.1")

# f1.put()

if hasattr(f1, "put"):

func_get = getattr(f1,'put')

func_get()

else:

print("********其他的逻辑********")

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# 正在连接服务器[ 1.1.1.1 ]

# ********其他的逻辑********

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 9.2、反射的应用,——部分功能已经完善

# # 假设如下场景,A,B同时开发一个程序,A开发 ftp_client 的功能还没有完善,但是B开发

# # # ftp_user 需要使用ftp_client的功能,此时这个功能就派上用场了

ftp_client.py文件内容:

class FtpClient:
'ftp客户端,但是还没有实现具体的功能'
def __init__(self, addr):
print("正在连接服务器[ %s ]" %addr)
self.addr = addr

def put(self):  
    print("正在上传文件!")

===========================

ftp_user.py文件内容:

from ftp_client import FtpClient
f1 = FtpClient("1.1.1.1")

f1.put()

if hasattr(f1, "put"):
func_get = getattr(f1,'put')
func_get()
else:
print("其他的逻辑")

------------------------------------------------------------

'''

from ftp_client import FtpClient

f1 = FtpClient("1.1.1.1")

# f1.put()

if hasattr(f1, "put"):

func_get = getattr(f1,'put')

func_get()

else:

print("其他的逻辑")

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# 正在连接服务器[ 1.1.1.1 ]

# 正在上传文件!

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 10、__import__('m1.t') 动态导入模块

================

模块路径:

D:\C_cache\py\day26_DuoTai_FengZhuang_FanShe\m1\t.py

================

t.py模块内容

def test1():
print("test1")

def test2():
print("test2")

================

当前工程路径:

D:\C_cache\py\day26_DuoTai_FengZhuang_FanShe\day26_DuoTai_FengZhuang_FanShe.py

------------------------------------------------------------

'''

# 不使用动态导入

from m1 import t # m1/t

t.test1()

t.test2()

print("分割线".center(100,"-"))

# 使用动态导入

module_t = __import__('m1.t') # m1/t

print(module_t)

module_t.t.test1()

module_t.t.test2()

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# test1

# test2

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

#

# test1

# test2

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 11、__import__('m1.t') 动态导入模块的内部函数

================

模块路径:

D:\C_cache\py\day26_DuoTai_FengZhuang_FanShe\m1\t.py

================

t.py模块内容

def test1():
print("test1")

def _test2(): # 内部函数,下划线开头

print("=====>>>>>  \_test2")

================

当前工程路径:

D:\C_cache\py\day26_DuoTai_FengZhuang_FanShe\day26_DuoTai_FengZhuang_FanShe.py

------------------------------------------------------------

'''

# 不使用动态导入

from m1 import t # m1/t

t.test1()

t._test2()

print("分割线".center(100,"-"))

# 使用动态导入

module_t = __import__('m1.t') # m1/t

print(module_t)

module_t.t.test1()

module_t.t._test2()

print("分割线".center(100,"-"))

from m1.t import *

test1()

# _test2() # 报错,无法导入内部函数

D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

test1

=====>>>>> _test2

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

test1

=====>>>>> _test2

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

test1

Process finished with exit code 0

'''

------------------------------------------------------------

# 12、__import__('m1.t') 动态导入模块的内部函数

================

模块路径:

D:\C_cache\py\day26_DuoTai_FengZhuang_FanShe\m1\t.py

================

t.py模块内容

def test1():
print("test1")

def _test2(): # 内部函数,下划线开头

print("=====>>>>>  \_test2")

================

当前工程路径:

D:\C_cache\py\day26_DuoTai_FengZhuang_FanShe\day26_DuoTai_FengZhuang_FanShe.py

------------------------------------------------------------

'''

import importlib

m = importlib.import_module('m1.t')

print(m)

m.test1()

m._test2()

print("分割线".center(100,"-"))

n = __import__('m1.t') # 这种方式导入时解释器内部自己使用的

print(n)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

#

# test1

# =====>>>>> _test2

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

#

#

# Process finished with exit code 0

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

09 类的内置attr属性

09 类的内置attr属性

'''

------------------------------------------------------------

# 13、__getattr__

# # 类中的__getattr__,查找属性不存在的时候,就会触发!

------------------------------------------------------------

'''

class Foo:

x = 1

def __init__(self, y):

self.y = y

def __getattr__(self, item):

# print('执行 __getattar__, 查找的属性不存在 %' %self.item) # 报错,RecursionError: maximum recursion depth exceeded while calling a Python object

print('执行 __getattar__, 查找【%s】属性不存在 '%item )

f1 = Foo(10)

print(f1.__dict__)

print(f1.y)

print(getattr(f1, 'y'))

print( f1.aaaaaa )

print(f1.__dict__)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# {'y': 10}

# 10

# 10

# 执行 __getattar__, 查找【aaaaaa】属性不存在

# None

# {'y': 10}

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 14、__delattr__删除操作

# # 删除的操作,相当于重写了类中的delattr。

# # 下列演示中,重写后的__delattr__中只是触发了__delattr__,没有触发删除指定的内容

------------------------------------------------------------

'''

class Foo:

x = 1

a = "a"

def __init__(self, y, b):

self.y = y

self.b = b

def __delattr__(self, item):

print('执行 __delattr__, 删除操作 ' )

f1 = Foo(10, "哈哈哈")

print(f1.__dict__)

del f1.y

del f1.x

delattr(f1,'b')

print(f1.__dict__)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# {'y': 10, 'b': '哈哈哈'}

# 执行 __delattr__, 查找的属性不存在

# 执行 __delattr__, 查找的属性不存在

# 执行 __delattr__, 查找的属性不存在

# {'y': 10, 'b': '哈哈哈'}

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 15、__setattr__设置属性操作之不允许添加

# # _setattr__添加/修改属性会触发它的执行

------------------------------------------------------------

'''

class Foo:

fx = 1

fa = "a"

def __init__(self, y, b):

self.y = y

self.b = b

def __setattr__(self, key, value):

print('执行 __setattr__, 设置属性操作 %s =%s' %( key, value) )

# 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值

# ,除非你直接操作属性字典,否则永远无法赋值

# 实例化

f1 = Foo(10, "哈哈哈")

print("f1.__dict__: ", f1.__dict__)

# 添加属性

f1.name = "傻帽儿"

f1.age = "66"

print("f1.__dict__: ", f1.__dict__)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# 执行 __setattr__, 设置属性操作 y =10

# 执行 __setattr__, 设置属性操作 b =哈哈哈

# f1.__dict__: {}

# 执行 __setattr__, 设置属性操作 name =傻帽儿

# 执行 __setattr__, 设置属性操作 age =66

# f1.__dict__: {}

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 15.1、__setattr__设置属性操作之添加内容

# # _setattr__添加/修改属性会触发它的执行

------------------------------------------------------------

'''

class Foo:

fx = 1

fa = "a"

def __init__(self, y, b):

self.y = y

self.b = b

def __setattr__(self, key, value):

# 报错,RecursionError: maximum recursion depth exceeded

# self.key = value ,导致一直调用__setattr__,因为实质上设置属性操作的是字典,

# self.key = value

# ===>>正确的方式

self.__dict__[key] = value

print('设置成功!!执行 __setattr__, 设置属性操作内容是: %s =%s' % (key, value))

# 因为你重写了__setattr__,凡是赋值操作都会触发它的运行

# 实例化

f1 = Foo(10, "哈哈哈")

print("f1.__dict__: ", f1.__dict__)

# 添加属性

f1.name = "傻帽儿"

f1.age = "66"

print("f1.__dict__: ", f1.__dict__)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# 设置成功!!执行 __setattr__, 设置属性操作内容是: y =10

# 设置成功!!执行 __setattr__, 设置属性操作内容是: b =哈哈哈

# f1.__dict__: {'y': 10, 'b': '哈哈哈'}

# 设置成功!!执行 __setattr__, 设置属性操作内容是: name =傻帽儿

# 设置成功!!执行 __setattr__, 设置属性操作内容是: age =66

# f1.__dict__: {'y': 10, 'b': '哈哈哈', 'name': '傻帽儿', 'age': '66'}

#

# Process finished with exit code 0

10 类内置attr属性补充

10 类内置attr属性补充

'''

------------------------------------------------------------

# 16、内置属性查询

# # 内置属性查询dir是将所有的列出来

------------------------------------------------------------

'''

class Foo:

pass

print("内置属性查询 Foo.__dict__: ", Foo.__dict__)

print("内置属性查询dir(Foo): ", dir(Foo))

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# Foo.__dict__: {'__module__': '__main__', '__dict__': , '__weakref__': , '__doc__': None}

# dir(Foo): ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 17、__getattr__, __delattr__, __setattr__的一些应用

------------------------------------------------------------

'''

class Foo:

def __getattr__(self, item):

print("没有【%s】属性 "%item)

def __delattr__(self, item):

print("不允许删除【%s】属性 "%item)

def __setattr__(self, key, value):

print("不允许添加【%s = %s】属性 " % (key, value) )

# 空的实例化

f1 = Foo()

print(f1.__dict__)

print(f1.x) # 只有在属性不存在时,会自动触发__getattr__

del f1.x # 删除属性时会触发 __delattr__

f1.name = "哈哈哈" # 设置属性的时候会触发——setattr———

f1.age = "66" # 设置属性的时候会触发——setattr———

print(f1.__dict__)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# {}

# 没有【x】属性

# None

# 不允许删除【x】属性

# 不允许添加【name = 哈哈哈】属性

# 不允许添加【age = 66】属性

# {}

#

# Process finished with exit code 0

11 继承的方式完成包装

11 继承的方式完成包装

'''

------------------------------------------------------------

# 18、继承的方式完成包装,__setattr__,添加属性指定,以及删除函数的原型

# # 添加属性的本质就是操作“属性字典”, f1.age = 333 等价于 self.__dict__[key] = value

# # 等价内容: f1 == self; age == key; value == 333

# # 下列中,只是允许字符串类型的添加

------------------------------------------------------------

'''

class Foo:

def __init__(self, name):

self.name = name

def __setattr__(self, key, value):

if type(value) is str:

self.__dict__[key] = value

print("设置完成!【%s = %s】"% (key, value))

else:

print("属性内容必须是字符串类型!不允许添加【%s = %s】属性 " % (key, value) )

f1 = Foo("alex")

f2 = Foo(22)

print("分割线".center(100,"-"))

print("f1.__dict__: ", f1.__dict__)

print("f2.__dict__: ", f2.__dict__)

f1.age = 333

f1.sex = "male"

print("分割线".center(100,"-"))

f2.age = 9999

f2.sex = "female"

print("分割线".center(100,"-"))

print("f1.__dict__: ", f1.__dict__)

print("f2.__dict__: ", f2.__dict__)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# 设置完成!【name = alex】

# 属性内容必须是字符串类型!不允许添加【name = 22】属性

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

# f1.__dict__: {'name': 'alex'}

# f2.__dict__: {}

# 属性内容必须是字符串类型!不允许添加【age = 333】属性

# 设置完成!【sex = male】

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

# 属性内容必须是字符串类型!不允许添加【age = 9999】属性

# 设置完成!【sex = female】

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

# f1.__dict__: {'name': 'alex', 'sex': 'male'}

# f2.__dict__: {'sex': 'female'}

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 19、继承的方式完成包装,__delattr__,以及删除函数的原型

# # 删除属性的本质就是操作“属性字典”, del f1.sex 等价于 self.__dict__.pop(item)

# # 等价内容: f1 == self; sex == item;

# #

------------------------------------------------------------

'''

class Foo:

def __init__(self, name):

self.name = name

def __delattr__(self, item):

# del self.item # 报错,等于与不断的调用__delattr__,RecursionError: maximum recursion depth exceeded while calling a Python object

self.__dict__.pop(item)

print("已删除【%s】属性 "%item)

f1 = Foo("alex")

f1.age = 333

f1.sex = "male"

print("f1.__dict__: ", f1.__dict__)

del f1.sex

print("分割线".center(100,"-"))

print("f1.__dict__: ", f1.__dict__)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# f1.__dict__: {'name': 'alex', 'age': 333, 'sex': 'male'}

# 已删除【sex】属性

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

# f1.__dict__: {'name': 'alex', 'age': 333}

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 20、list类继承与函数属性添加

------------------------------------------------------------

'''

class List(list):

def show_middle(self):

mid_index = int(len(self)/2)

return self[mid_index]

l1 = List("hello+world!")

l2 = list("hello+world!")

print(l1, type(l1)) # 当前List下的类,与下面的l2的类型是不一样的

print(l2, type(l2))

print(l1.show_middle())

# 函数属性继承

l1.append(9999)

l1.append("AAAAA")

print(l1)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# ['h', 'e', 'l', 'l', 'o', '+', 'w', 'o', 'r', 'l', 'd', '!']

# ['h', 'e', 'l', 'l', 'o', '+', 'w', 'o', 'r', 'l', 'd', '!']

# w

# ['h', 'e', 'l', 'l', 'o', '+', 'w', 'o', 'r', 'l', 'd', '!', 9999, 'AAAAA']

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 21、list类继承与函数属性append修改

------------------------------------------------------------

'''

class List(list):

def show_middle(self):

mid_index = int(len(self)/2)

return self[mid_index]

def append(self, p_object):

# self.append(p_object) # 报错,会一直递归调用该函数;RecursionError: maximum recursion depth exceeded

if type(p_object) is str:

list.append(self, p_object) # 使用继承过来的函数属性append

else:

print("不允许添加【%s】!只能添加字符串类型"%p_object)

l1 = List("hello+world!")

l2 = list("hello+world!")

print(l1, type(l1)) # 当前List下的类,与下面的l2的类型是不一样的

print(l2, type(l2))

print(l1.show_middle())

# 函数属性继承 与修改

l1.append(9999)

l1.append("AAAAA")

print(l1)

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# ['h', 'e', 'l', 'l', 'o', '+', 'w', 'o', 'r', 'l', 'd', '!']

# ['h', 'e', 'l', 'l', 'o', '+', 'w', 'o', 'r', 'l', 'd', '!']

# w

# 不允许添加【9999】!只能添加字符串类型

# ['h', 'e', 'l', 'l', 'o', '+', 'w', 'o', 'r', 'l', 'd', '!', 'AAAAA']

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 21.1、list类继承与函数属性append修改,super()

------------------------------------------------------------

'''

class List(list):

def show_middle(self):

mid_index = int(len(self)/2)

return self[mid_index]

def append(self, p_object):

# self.append(p_object) # 报错,会一直递归调用该函数;RecursionError: maximum recursion depth exceeded

if type(p_object) is str:

# list.append(self, p_object) # 使用继承过来的函数属性append

super().append(p_object) # 等价于list.append(self, p_object)

else:

print("不允许添加【%s】!只能添加字符串类型"%p_object)

l1 = List("hello+world!")

l2 = list("hello+world!")

print(l1, type(l1)) # 当前List下的类,与下面的l2的类型是不一样的

print(l2, type(l2))

print(l1.show_middle())

# 函数属性继承 与修改

l1.append(9999)

l1.append("AAAAA")

print(l1)

D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

['h', 'e', 'l', 'l', 'o', '+', 'w', 'o', 'r', 'l', 'd', '!']

['h', 'e', 'l', 'l', 'o', '+', 'w', 'o', 'r', 'l', 'd', '!']

w

不允许添加【9999】!只能添加字符串类型

['h', 'e', 'l', 'l', 'o', '+', 'w', 'o', 'r', 'l', 'd', '!', 'AAAAA']

Process finished with exit code 0

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

12 组合的方式完成授权

12 组合的方式完成授权

'''

------------------------------------------------------------

# 22、授权的概念:

# # 授权:授权是包装的一个特性, 包装一个类型通常是对已存在的类型的一些定制,这种做法

# # 可以新建,修改或删除原有产品的功能。其它的则保持原样。授权的过程,即是所有更新的功

# # 能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

# #

# # 实现授权的关键点就是覆盖__getattr__方法

------------------------------------------------------------

'''

'''

------------------------------------------------------------

# 23、授权__getattr__

=================

文件a.txt内容:

这个是a.txt文件

------------------------------------------------------------

'''

class FileHandle:

def __init__(self, filename, mode = 'r', encoding = 'utf-8'):

self.file = open( filename, mode, encoding=encoding ) # 通过内置的open函数拿到文件句柄

self.mode = mode

self.encoding = encoding

def __getattr__(self, item):

'当属性不存在的时候,会触发该函数,于是会self.file里头去找相关的属性====>>授权'

return getattr(self.file, item)

f1 = FileHandle('a.txt', 'r+')

print(f1.__dict__)

print("分割线".center(100,"-"))

print("f1.file: ", f1.file)

print( "f1.read() ", f1.read() ) # 这个是读取a.txt文件内容

print( "f1.read : ", f1.read )

print("分割线".center(100,"-"))

f1.write('<----->这个是新写入的内容!!')

# 读出来是空,是因为写入之后文件的定位光标的位置在文件的末尾处

print( "f1.read() ", f1.read() )

print("分割线".center(100,"-"))

# 把光标的位置移动回文件的开始位置

f1.seek(0)

print( "f1.read() ", f1.read() ) # 这个是a.txt文件

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# {'file': <_io.TextIOWrapper name='a.txt' mode='r+' encoding='utf-8'>, 'mode': 'r+', 'encoding': 'utf-8'}

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

# f1.file: <_io.TextIOWrapper name='a.txt' mode='r+' encoding='utf-8'>

# f1.read() 这个是a.txt文件

# f1.read :

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

# f1.read()

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

# f1.read() 这个是a.txt文件<----->这个是新写入的内容!!

#

# Process finished with exit code 0

'''

------------------------------------------------------------

# 23、授权__getattr__, 应用2 在指定的信息前面加入写入时间

=================

文件a.txt内容:

这个是a.txt文件

------------------------------------------------------------

'''

import time

class FileHandle:

def __init__(self, filename, mode = 'r', encoding = 'utf-8'):

self.file = open( filename, mode, encoding=encoding ) # 通过内置的open函数拿到文件句柄

self.mode = mode

self.encoding = encoding

def write(self, line):

print('**写入内容是**:%s'%line)

t = time.strftime('%Y-%m-%d %X')

self.file.write('%s %s'%(t, line))

def __getattr__(self, item):

'当属性不存在的时候,会触发该函数,于是会self.file里头去找相关的属性====>>授权'

return getattr(self.file, item)

f1 = FileHandle('a.txt', 'r+')

print(f1.__dict__)

print("分割线".center(100,"-"))

print("f1.file: ", f1.file)

print( "f1.read() ", f1.read() ) # 这个是读取a.txt文件内容

print( "f1.read : ", f1.read )

print("分割线".center(100,"-"))

f1.write('CPU负载过高!!\n')

f1.write('内存剩余不足!!\n')

f1.write('硬盘剩余不足!!\n')

print("分割线".center(100,"-"))

# 把光标的位置移动回文件的开始位置

f1.seek(0)

print( "f1.read() ", f1.read() ) # 这个是a.txt文件

D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

{'file': <_io.TextIOWrapper name='a.txt' mode='r+' encoding='utf-8'>, 'mode': 'r+', 'encoding': 'utf-8'}

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

f1.file: <_io.TextIOWrapper name='a.txt' mode='r+' encoding='utf-8'>

f1.read() 这个是a.txt文件

f1.read :

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

**写入内容是**:CPU负载过高!!

**写入内容是**:内存剩余不足!!

**写入内容是**:硬盘剩余不足!!

# D:\Anaconda3\python.exe D:/C_cache/py/day26_DuoTai_FengZhuang_FanShe/day26_DuoTai_FengZhuang_FanShe.py

# {'file': <_io.TextIOWrapper name='a.txt' mode='r+' encoding='utf-8'>, 'mode': 'r+', 'encoding': 'utf-8'}

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

# f1.file: <_io.TextIOWrapper name='a.txt' mode='r+' encoding='utf-8'>

# f1.read() 这个是a.txt文件

#

# f1.read :

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

# **写入内容是**:CPU负载过高!!

#

# **写入内容是**:内存剩余不足!!

#

# **写入内容是**:硬盘剩余不足!!

#

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

# f1.read() 这个是a.txt文件

# 2018-08-13 14:16:14 CPU负载过高!!

# 2018-08-13 14:16:14 内存剩余不足!!

# 2018-08-13 14:16:14 硬盘剩余不足!!

#

#

# Process finished with exit code 0