Python CookBook 第八章 类与对象(下)

目录

8.15委托属性的访问

 8.16在类中定义多个构造函数

8.17 不通过调用init来创建实例

8.18用Mixin类来扩展类定义

8.19实现带有状态的对象和状态机

8.20 调用对象上的方法,方法名以字符串形式给出

8.24让类支持比较操作

8.25 创建缓存实例


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()._
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值