打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
python – 基于值而不是类型的Singledispatch

我在Django上构建SPA,我有一个巨大的函数,有很多if语句用于检查我的对象字段的状态名称.像这样:

if self.state == 'new':    do some logicif self.state == 'archive':    do some logic

等等.我现在阅读好书“Fluent python”,我提到了@singledispatch装饰器,它看起来很棒,但它只能用不同类型的参数如str,int等覆盖函数.
问题是,如果在python或Django方式中分离逻辑就像在我的庞大函数中使用像singledispatch那样的重叠函数吗?

解决方法:

有,但你必须写它.一种可能性是创建一个基于instance.state或任何选择的state_attr进行调度的descriptor

class StateDispatcher(object):    def __init__(self, state_attr='state'):        self.registry = {}        self._state_attr = state_attr    def __get__(self, instance, owner):        if instance is None:            return self        method = self.registry[getattr(instance, self._state_attr)]        return method.__get__(instance, owner)    def register(self, state):        def decorator(method):            self.registry[state] = method            return method        return decorator

https://docs.python.org/3/howto/descriptor.html#functions-and-methods

To support method calls, functions include the __get__() method for binding methods during attribute access. This means that all functions are non-data descriptors which return bound or unbound methods depending whether they are invoked from an object or a class.

在您的有状态类中,您可以创建一个调度程序并注册方法:

class StateMachine(object):    dispatcher = StateDispatcher()    state = None    @dispatcher.register('test')    def test(self):        print('Hello, World!', self.state)    @dispatcher.register('working')    def do_work(self):        print('Working hard, or hardly working?', self.state)

让我们看看它的实际效果:

>>> sm = StateMachine()>>> sm.state = 'test'>>> sm.dispatcher()Hello, World! test>>> sm.state = 'working'>>> sm.dispatcher()Working hard, or hardly working? working>>> sm.state = None>>> sm.dispatcher()Traceback (most recent call last):  ...  File "dispatcher.py", line 11, in __get__    method = self.registry[getattr(instance, self._state_attr)]KeyError: None

请注意,这是一种基于状态调度的非常恶劣的方法,因为对于未来的代码读者来说,整个机制将很难遵循.

另一种调度文本状态的方法是对方法名称中的状态进行编码,并在调度函数中根据该方法选择正确的方法.许多python类使用此模式(例如ast.NodeVisitor):

class StateMachine(object):    def dispatch(self, *args, **kwgs):        getattr(self, 'do_{}'.format(self.state))(*args, **kwgs)    def do_new(self):        print('new')    def do_archive(self):        print('archive')sm = StateMachine()sm.state = 'new'sm.dispatch()sm.state = 'archive'sm.dispatch()
来源:http://www.icode9.com/content-1-231851.html
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Python学习笔记《Python核心编程》第13章 面向对象编程
如何使用三种不同的方式生成python源代码,提高开发效率?
Python 中惊人的 Functools 特性
python实现事件监听
如何利用Python标准库编程
Python人工智能算法工具包:SimpleAI
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服