#!/usr/bin/env python
# -*- coding:utf-8 -*-
四个方法的使用演示
class BlackMedium:
feature = 'Ugly'
def __init__(self,name,addr):
self.name = name
self.addr = addr
def sell_hours(self):
print("%s 不傻" %self.name)
def ren_hours(self):
print("%s 不租" %self.addr)
b1 = BlackMedium('金三角','锦绣华城')
# 判断类b1 中是否有一个name字符串对应的方法或属性
print(hasattr(b1,'addr',))
# 判断类b1 中是否有一个ren_hours字符串对应的方法或属性
print(hasattr(b1,'ren_hours'))
# 获取属性
n = getattr(b1,'name')
print(n)
m = getattr(b1,'sell_hours')
m()
#设置属性
setattr(b1,'sb',True)
setattr(b1,'show_name',lambda self:self.name+'sb')
print(b1.__dict__)
print(b1.show_name(b1))
# 删除属性
delattr(b1,'addr')
delattr(b1,'show_name')
# delattr(b1,'show_name1111')#不存在,就报错
print(b1.__dict__)
******类也是对象*******
class Foo(object):
staticField = 'oldboy'
def __init__(self):
self.name = 'wupeiqi'
def func(self):
return 'func'
@staticmethod
def bar():
return 'bar'
print(getattr(Foo,'staticField'))
print(getattr(Foo,'func'))
print(getattr(Foo,'bar'))
反射当前模块成员
import sys
def s1():
print('s1')
def f2():
print('s2')
this_module = sys.modules[__name__]
a = hasattr(this_module,'s1')
b = hasattr(this_module,'s2')
print(a)
print(b)
三__setattr__,__delattr__,__getattr__
class Foo:
x = 1
def __init__(self,y):
self.y = y
def __getattr__(self, item):
print('-->from getattr:你找的属性不存在:')
def __setattr__(self, key, value):
print('--> from setattr')
# self.key = value
# self.__dict__[key] = value
def __delattr__(self, item):
print('--> from delattr')
# del self.item
self.__dict__.pop(item)
property
四,二次加工标准类型(包装)
基于继承实现
class List(list):
def append(self, p_object):
if not isinstance(p_object,int):
raise TypeError('must be int')
super().append(p_object)
@property
def mid(self):
index = len(self)//2
return self[index]
l = List([1,2,3,4])
print(l)
l.append(5)
print(l)
print(l.mid)
l.insert(1,-123)
print(l)
print(len(l))
l.clear()
print(l)
# 练习,(clear 加权限限制)
class List(list):
def __init__(self,item,tag = False):
super().__init__(item)
self.tag = tag
def append(self, p_object):
if not isinstance(p_object, int):
raise TypeError
super().append(p_object)
def clear(self):
if not self.tag:
raise PermissionError
super().clear()
l = List([1,2,3],False)
print(l)
print(l.tag)
l.append(123)
print(l)
l.tag = True
print(l.tag)
l.clear()
print(l)
# ***授权***
实现授权的关键点就是覆盖__getattr__方法
import time
class FileHandle:
def __init__(self,filename,mode = 'r',encoding = 'utf-8'):
self.file = open(filename,mode,encoding='utf-8')
def write(self,line):
t = time.strftime('%Y-%m-%d %T')
self.file.write('%s %s '%(t,line))
def __getattr__(self, item):
return getattr(self.file,item)
f1 = FileHandle('b.txt','w+')
f1.write('你好啊')
f1.seek(10)
print(f1.read())
f1.close()
# 授权示范二
# __author__ = 'linhaifeng'
# 我们来加上b模式支持
"""
import time
class FileHandle:
def __init__(self,filename,mode = 'r',encoding = 'utf-8'):
if 'b' in mode:
self.file = open(filename,mode)
else:
self.file == open(filename,mode,encoding= encoding)
self.filename = filename
self.mode = mode
self.encoding = encoding
def wriet(self,line):
if 'b' in self.mode:
if not isinstance(line,bytes):
raise TypeError('must be bytes')
self.file.write(line)
def __getattr__(self, item):
return getattr(self.file,item)
def __str__(self):
if 'b' in self.mode:
res = "<_io.BufferedReadr name ='%s'>"%self.filename
else:
res = "<_io Text|OWrapper name = '%s' mode = '%s' encoding = '%s'>" %(self.filename,self.mode,self.encoding)
return res
f1 = FileHandle('b.txt','wb')
f1.wriet("你好啊".encode('utf-8'))
print(f1)
f1.close()
# 练习题(授权)
# 练习一
"""
class List:
def __int__(self,seq):
self.seq = seq
def append(self,p_object):
if not isinstance(p_object,int):
raise TypeError('must be int')
self.seq.append(p_object)
@property
def mid(self):
index = len(self.seq)//2
return self.seq[index]
def __getattr__(self, item):
return getattr(self.seq,item)
def __str__(self):
return str(self.seq)
l = List([1,2,3,4])
print(l)
l.append(4)
print(l)
print(l.mid)
"""
# 五、、__getattribute__
"""
class Foo:
def __init__(self,x):
self.x = x
def __getattr__(self, item):
print('执行的是我')
# return self.__dict__[item]
f1 = Foo(10)
print(f1.x)
f1.xxxxxxx#不存在的属性访问,触发__getattr__
# getattribute
class Foo:
def __init__(self,x):
self.x =x
def __getattribute__(self, item):
print("不管是否存在,我都会执行")
f1 = Foo(10)
f1.x
f1.xxxxx
"""
# 六 、描述符(__get__,__set__,__delete__)
# 1 描述符是什么:描述符本身就是一个新式类,在这个新式类中,至少实现了__get__(),__set__(),__delete__()中的一个,
# 这个也被称为描述符协议__get__():调用一个属性时,触发。__get__():为一个属性赋值时,触发。
# __delete__():采用del删除属性时,触发
# 定义一个描述符
"""
class Foo:
def __get__(self,instance,owner):
pass
def __set__(self,instance,value):
pass
def __delete__(self, instance):
pass
"""
# 2.描述符是干什么的:描述符的作用是用来代理另外一个类属性的(必须把描述符定义成这个类的类属性,不能定义到构造函数中)
"""
class Str:
def __get__(self, instance, owner):
print('Str 调用')
def __set__(self, instance, value):
print('Str 设置。。。')
def __delete__(self, instance):
print('Str 删除。。。')
class Int:
def __get__(self, instance, owner):
print('Int 调用')
def __set__(self, instance, value):
print('Int 设置。。。')
def __delete__(self, instance):
print('Int 删除。。。')
class People:
name = Str()
age = Int()
def __init__(self,name,age):
self.name = name
self.age = age
p1 = People('alex',18)
p1.name
p1.name = 'egon'
del p1.name
p1.age
p1.age = 18
del p1.age
print(p1.__dict__)
print(People.__dict__)
print(type(p1) == People)#type(obj)其实是查看obj是由哪个类实例化来的
print(type(p1).__dict__ == People.__dict__)
"""
# 修订__get__方法
"""
class Str:
def __init__(self,name):
self.name = name
def __get__(self,instance,owner):
print("get-->",instance,owner)
if instance is None:
return self
return instance.__dict__[self.name]
def __set__(self, instance, value):
print("ste-->",instance,value)
instance.__dict__[self.name] = value
def __delete__(self, instance):
print('__delete__-->',instance)
instance.__dict__.pop(self.name)
class People:
name = Str('name')
def __init__(self,name,age,salary):
self.name = name
self.age = age
self.salary = salary
print(People.name)
"""
# 类的装饰器 :无
def decorate(cls):
print('类的装饰器开始运行了')
return cls
@decorate
class People:
def __init__(self,name,age,salary):#salary 薪水
self.name = name
self.age = age
self.salary = salary
p1 = People('alex',18,3000)
# 类的装饰器:无参
def Typeassert(**kwargs):
def decorate(cls):
print('类的装饰器开始运行了',kwargs)
return cls
return decorate
@Typeassert(name = atr,age = int,salary = float)
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @property回顾
"""
class Room:
def __init__(self,name,width,length):
self.name = name
self.width = width
self.length = length
@property
def area(self):
return self.width * self.length
r1 = Room('alex',2,3)
print(r1.area)
"""
# 自己做一个@property
"""
class lazyproperty:
def __init__(self,func):
self.func = func
def __get__(self, instance, owner):
print('这是我自己制定的静态属性,r1.area 实际上是要执行 r1.area()')
if instance is owner:
return self
return self.func(instance)
class Room:
def __init__(self,name,width,length):
self.name = name
self.width = width
self.length = length
@lazyproperty
def area(self):
return self.width * self.length
r1 = Room('alex',2,3)
print(r1.area)
"""
# 实现延迟计算功能
"""
class Lazyproperty:
def __init__(self,func):
self.func = func
def __get__(self, instance, owner):
print("这是自己定制的静态属性,r1.area 实际上是要执行r1.area()")
if instance is None:
return self
else:
print("-->")
value = self.func(instance)
setattr(instance,self.func.__name__,value)
return value
class Room:
def __init__(self,name,width,length):
self.name = name
self.width = width
self.length = length
@Lazyproperty #area = Lazyproperty(area) 相当于定义了一个类属性,即描述符
def area(self):
return self.width * self.length
r1 = Room('ouayng',2,3)
print(r1.area)
print(r1.area)
"""
# 六 再看property
# 一个静态属性property本质就是实现了get,set,delete 三种方法
# 用法一:
"""
class Foo:
@property
def BBB(self):
print("get 的时候运行")
@BBB.setter
def BBB(self,value):
print("set 的时候运行")
@BBB.deleter
def BBB(self):
print("delter 的时候运行")
# 只有在属性BBB定义property之后才能定义BBB.setter,BBB.deleter
f1 = Foo()
f1.BBB
f1.BBB = 'aaa'
del f1.BBB
"""
# 用法二
"""
class Foo:
def get_BBB(self):
print("get 的时候运行")
def set_BBB(self, value):
print("set 的时候运行")
def deleter_BBB(self):
print("delter 的时候运行")
BBB = property(get_BBB,set_BBB,deleter_BBB)
f1 = Foo()
f1.BBB
f1.BBB = 'aaa'
del f1.BBB
"""
# 怎么用
# ******案例一*******
"""
class Goods:
def __init__(self):
self.original_price = 100
self.discount = 0.8
def get_price(self):
new_price = self.original_price * self.discount
return new_price
def set_pricce(self,value):
self.original_price = value
def deleter_price(self):
del self.original_price
price = property(get_price,set_pricce,deleter_price)
obj = Goods()
obj.get_price
obj.price = 80
print(obj.price)
del obj.price
"""
# 从写案例一
"""
class Goods:
def __init__(self):
self.original_price = 100
self.discount = 0.8
@property
def price(self):
new_price = self.original_price * self.discount
return new_price
@price.setter
def price(self,value):
self.original_price = value
@price.deleter
def deleter(self):
del self.original_price
obj = Goods()
yj = obj.original_price
print(yj)
obj.price
obj.price = 20
print(obj.price)
obj.deleter
print(obj.deleter)
"""
# *****案例二******
# 实现类型检测功能
# 第一关
# class People:
# def __init__(self,name):
# self.name = name
#
# @property
# def name(self):
# return self.name
# 第二关:修订版
"""
class People:
def __init__(self,name):
self.name = name# 实例化就触发property
@property
def name(self):
# return self.name 无限递归
print('get--->')
return self.DouNiWan
@name.setter
def name(self,value):
print('set-->')
self.DouNiWan = value
@name.deleter
def name(self):
print('delete-->')
del self.DouNiWan
p1 = People('alex')
print(p1.name)
# print(p1.name)
# print(p1.name)
print(p1.__dict__)
p1.name = 'egon'
print(p1.__dict__)
del p1.name
print(p1.__dict__)
"""
# 七、 __setitem__,__getitem__,__delitem__
"""
class Foo:
def __init__(self,name):
self.name = name
def __getitem__(self, item):
print(self.__dict__[item])
def __setitem__(self, key, value):
self.__dict__[key] = value
def __delitem__(self, key):
print('del obj[key]时,我执行')
self.__dict__.pop(key)
def __delattr__(self, item):
print('del obj.key 时,我执行')
self.__dict__.pop(item)
f1 = Foo('sb')
f1['age'] = 18
f1["age1"] = 19
del f1.age1
del f1['age']
f1['name'] = 'alex'
print(f1.__dict__)
"""
# 八、__str__,__repr__,__format__
# 改变对象的字符串显示 __str__,__repr__
# 自定制格式化字符串__format__
"""
__author__ = 'linhaifeng'
format_dic = [
'nat':'{obj.name}-{obj.addr}-{obj.type}'
'tna':''
]
"""
# 九、 slots
# 1,含义:__slots__是一个类变量,变量值可以是列表,元组,或者可迭代对象,也可以是一个字符串
# 2、引子、使用点来访问属性本质就是在访问类或者对象的__dict__属性字典(类的字典是共享的,每个实例是独立的)
# __slots__会为实例使用一种更加紧凑的内部表示,很多特性都依赖于字典,
# 常见误区:它可以作为一个封装工具来防止用户给实例增加新的属性
# 简而言之,__slots__就是一个字典,只能被付一次值
"""
class Foo:
__slots__ = 'x'
f1 = Foo()
f1.x = 1
f1.x = 2#报错
f1.x = 3
print(f1.__slots__)
"""
"""
class Bar:
__slots__ = ['x','y']
n = Bar()
n.x,n.y = 1,2
# n.z = 3
print(n.__slots__)
"""
# 刨根问底
"""
class Foo:
__slots__ = ['name','age']
f1 = Foo()
f1,name = 'alex'
f1.age = 18
print(f1.__slots__)
f2 = Foo()
f2.name = 'egon'
f2.age = '19'
print(f2.__slots__)
print(Foo.__slots__)
f1,f2都会报错,f1,f2都没有属性字典__dict__了,统一归__slots__管,节省内存。
"""
# 十、__next__和__iter__ 实现迭代器协议
# 简单示范
"""
import time
class Foo:
def __init__(self,x):
self.x =x
def __iter__(self):
return self
def __next__(self):
n = self.x
self.x += 1
return self.x
f1 = Foo(3)
for i in f1:
print(i)
time.sleep(1)
"""
"""
class Foo:
def __init__(self,start,stop):
self.num = start
self.stop = stop
def __iter__(self):
return self
def __next__(self):
if self.num >= self.stop:
raise StopIteration
n = self.num
self.num += 1
return n
f = Foo(1,5)
from collections import Iterable,Iterator
print(isinstance(f,Iterator))
for i in Foo(1,5):
print(i)
"""
# 练习:简单模拟range,加上步长
"""
class Range:
def __init__(self,n,stop,step):
self.n = n
self.stop = stop
self.step = step
def __next__(self):
if self.n >= self.stop:
raise StopIteration
x = self.n
self.n += self.step
return x
def __iter__(self):
return self
for i in Range(1,7,3):
print(i)
"""
# 斐波那契数列
"""
class Fib:
def __iter__(self):
self._a = 0
self._b = 1
def __iter__(self):
return self
def __next__(self):
self._a,self._b = self._b,self._a + self._b
return self._a
f1 = Fib()
print(f1.__next__())
print(next(f1))
print(next(f1))
for i in f1:
if i > 100:
break
print('%s' %i,end='')
"""
# 十一、__doc__
"""
# 它类的描述信息
class Foo:
print('我是描述信息')
pass
print(Foo.__doc__)
# 该属性无法被继承
class Foo:
print('我是描述信息')
pass
class Bar(Foo):
print('我是子类')
pass
print(Bar.__doc__)#该属性无法继承子类
"""
# 十二、__module__ ,__class__
# __module__表示当前操作的对象在那个模块
# __class__ 表示当前操作的对象的类是什么
# 十三、__del__
# 清楚对象的同时回收系统资源,用到__del__
"""
class Foo:
def __del__(self):
print('执行我了')
f1 = Foo()
del f1#这时会执行def __del__(self) 内容
print("------->")
"""
# 十四,__enter__, __exit__
"""
class Open:
def __init__(self,name):
self.name = name
def __enter__(self):
print('出现with 语句 ,对象的__enter__被触发,有返回值则赋值给as 声明的变量')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('with 中代码块执行完毕时执行我啊')
with Open('a.txt') as f:
print('执行代码块')
print(f,f.name)
"""
#__exit__() 中的 三个参数分别代表异常类型,异常值,和追溯信息,with 语句中的代码块出现异常
# ,则with 后代码都无法执行
"""
class Open:
def __init__(self,name):
self.name = name
def __enter__(self):
print("出现with 语句,对象的__enter__被触发,有返回值则赋值给as 声明的变量")
def __exit__(self, exc_type, exc_val, exc_tb):
print('with 中的代码执行完毕')
print(exc_type)
print(exc_val)
print(exc_tb)
with Open('a.txt') as f:
print('=====>执行代码块')
raise AttributeError('***着火了,救火了****')
print('0'*100)#不会执行
"""
# 十五、__call__
# 对象后加括号,触发执行
# 注:构造方法的执行是由创建对象触发的,即:对象 = 类名():
# 而对于__call__方法的执行是由对象后加括号触发的,即 对象()或者 类()()
"""
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print("类后面加上俩括号会执行__call__")
print('__call__')
# obj = Foo()
# obj()
Foo()()
"""