zoukankan      html  css  js  c++  java
  • python cookbook第三版学习笔记十七:委托属性

    我们想在访问实例的属性时能够将其委托到一个内部持有的对象上,这经常用到代理机制上

    class A:
        def spam(self,x):
            print("class_A:"+str(x))
        def foo(self):
            pass

    class B:
        def __init__(self):
            self._a=A()
        def bar(self):
            pass
        def __getattr__(self, item):
            return getattr(self._a,item)

    b=B()

    b.bar()

    b.spam(42)

    运行结果:

    class_A:42

    在这里,当调用b.spam的时候,由于查找不到这个属性,因此调用__getattr__来查找所有的属性。在上面的代码中,在访问B中未定义的方法时就把这个操作委托给A。

    对这种方法进行扩展一下,我们可以实现带有状态的对象或状态机。代码如下:

    class connection():

        def __init__(self):

            self.new_state(ClosedConnection)

        def new_state(self,newstate):

            self.__class__=newstate

        def read(self):

            raise NotImplementedError()

        def write(self):

            raise NotImplementedError()

        def open(self):

            raise NotImplementedError

        def close(self):

            raise NotImplementedError

    class ClosedConnection(connection):

        def read(self):

            raise RuntimeError('not open')

        def write(self,data):

            raise RuntimeError('not open')

        def open(self):

            self.new_state(OpenConnection)

        def close(self):

            raise RuntimeError('Already closed')

    class OpenConnection(connection):

        def read(self):

            print('reading')

        def write(self,data):

            print('writing')

        def open(self):

            raise RuntimeError('Already open')

        def close(self):

            self.new_state(ClosedConnection)

    c=connection()

    print(c)

    c.read()

    执行结果如下,初始状态为ClosedConnection, 调用read的时候提示not open

    <__main__.ClosedConnection object at 0x00000250CD984DD8>

    Traceback (most recent call last):

      File "D:/py_prj/test2/cookbook.py", line 152, in <module>

        c.read()

      File "D:/py_prj/test2/cookbook.py", line 130, in read

        raise RuntimeError('not open')

    RuntimeError: not open

    c=connection()

    print(c)

    c.open()

    print(c)

    c.read()

    c.write('abc')

    c.close()

    print(c)

    调用c.open后状态转移到OpenConnection。此时调用read和write方法则可以正常调用。调用close方法后状态转移到ClosedConnection

    <__main__.ClosedConnection object at 0x000001C495E94DA0>

    <__main__.OpenConnection object at 0x000001C495E94DA0>

    reading

    writing

    <__main__.ClosedConnection object at 0x000001C495E94DA0>

    通过这种方法减少了在代码分支中大量使用ifelse的调用。

  • 相关阅读:
    页面头部出现空白,页面头部出现 隐藏字符
    使用TortoiseGit对Git版本进行分支操作
    文件夹添加右键DOS快捷入口
    android离线安装adt
    V9最新手机门户域名绑定教程。
    phpcms v9 模板标签说明整理
    CAM350 10.5移动和叠层的用法
    MOS简单应用
    c语言知识点总结-------静态区、堆、栈、常量区等
    C语言关键字—-sizeof 、typedef、const、static、register、extern、#define
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/9501473.html
Copyright © 2011-2022 走看看