• 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的调用。

  • 相关阅读:
    C# 延时不卡界面
    C++ 转C#
    CYQ数据库配置
    VB Modbus RTU CRC 校验
    开始写博客了
    简单工厂模式
    单例模式
    基础、hibernate目前应用的对比
    QT Creator 代码自动补全---快捷键设定
    C# CMD直接运行语句
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/9501473.html
Copyright © 2020-2023  润新知