目录
8.15委托属性的访问
# 8.15委托属性的访问
# 委托是一种编程模式,我们将某个特定的操作转交另一个不同的额对象实现,简单来说就是这样的
class A:
def spam(self,x):
pass
def foo(self):
pass
class B:
def __init__(self):
self._a = A()
def sapm(self,x):
return self._a.spam(x)
def foo(self):
return self._a.foo()
#实现代理的一个例子
class Proxy:
def __init__(self,obj):
self._obj = obj
#委托属性浏览内部属性
def __getattr__(self, name):
print('Getting:',name)
return getattr(self._obj,name)
#委托属性设置
def __setattr__(self, name, value):
if name.startswith('_'):
super().__setattr__(name,value)
else:
print('setattr:',name,value)
setattr(self._obj,name,value)
#委托属性删除
def __delete__(self, name):
if name.startswith('_'):
super().__delattr__(name)
else:
print('Deleting:',name)
delattr(self._obj,name)
#使用这个代理类
class Spam:
def __init__(self,x):
self.x = x
def bar(self,y):
print('Spam.bar:',self.x,y)
#创建一个实例
a = Spam(2)
#创建一个委托
s = Proxy(a)
print(s.x)
# Getting: x
# 2
s.bar(3)
# Getting: bar
# Spam.bar: 2 3
s.x = 37
# set
8.16在类中定义多个构造函数
# 用户不限于__init__()提供的方法来创建实例
import time
class Date:
#第一种
def __init__(self,year,month,day):
self.year = year
self.month = month
self.day = day
#另一种
@classmethod
def today(cls):
t = time.localtime()
return cls(t.tm_year,t.tm_mon,t.tm_mday)
#会用这个构造函数
a = Date(2022,5,16)
b = Date.today()
8.17 不通过调用init来创建实例
class Date:
def __init__(self,year,month,day):
self.year = year
self.month = month
self.day = day
d = Date.__new__(Date)
print(d)
d.year = 2022
d.month = 5
d.day = 16
print(d.year,d.month,d.day) #2022 5 16 原文中不能直接设置,可能版本更新,可以直接设置响应的值
data = {'year':2022,'month':5,'day':17} #实现字典的反序列化,将字典转化为实例
for key,value in data.items():
setattr(d,key,value)
print(d.year,d.month,d.day)
8.18用Mixin类来扩展类定义
# 在类进行定制化处理时,我们有兴趣将各种各样的定制化处理方法添加到映射方法中
class LoggeMappingMixin:
#添加一些日志设置检查的功能
__slots__ = ()
def __getitem__(self, key):
print('Getting:' + str(key))
return super().__getitem__(key) #在这里使用super()是必要的,通过这个函数将任务转交给解析顺序(MRO)上的下一个类
def __setattr__(self, key, value):
print('Setting {} = {!r}'.format(key,value))
return super()._