开发者社区> 问答> 正文

Python简单使用插件结构:报错 

假设有一个验证密码的需求,会有很多限制条件,比如密码长度大于某一值,密码字符不全为数字,密码字符不全为字母等等。

最简单粗暴的方法如下:

def valid_password(pwd=''):
    if len(pwd)<6:
        raise ValueError('Passwords must be at least 6 characters')
    if pwd.isalnum():
        raise ValueError('Passwords must contain at least one special character')
    ...

当然由于需求很简单,所以堆在一个方法中也不觉得很糟糕,但是如果这样的if变得很多,很复杂,这么堆积就不可取了。 现在就用插件的方式来处理: 定义一个元类,使密码验证的基类在被继承时自动添加子类”插件“

class PluginMount(type):
    def __init__(cls,name,bases,attrs):
        if not hasattr(cls,'plugins'):
            cls.plugins=[]
        else:
            cls.plugins.append(cls)

创建密码验证基类,也就是总的”插件“管理器:

class PasswordValidator(object):
    __metaclass__=PluginMount
    def validate(self,pwd):
        raise NotImplementedError()

创建各个子类密码验证”插件“: 长度验证

class MinimumLength(PasswordValidator):
    def validate(self,pwd):
        if len(pwd)<6:
            raise ValueError('Passwords must be at least 6 characters')

字符验证

class SpecialCharacters(PasswordValidator):
    def validate(self,pwd):
        if pwd.isalnum():
            raise ValueError('Passwords must contain at least one special character')

等等验证。。。 最终密码验证方法:

def valid_password(pwd=''):
    for plugin in PasswordValidator.plugins:
        plugin().validate(pwd)

看起来确实多了很多代码,但是好处也是很明显的。在之前的密码验证方法中,如有任何修改,都需要修改原方法,而且密码验证会随着需求的增多而变得越来越难维护; 在新的插件方式中,如果你有新的需求,直接添加密码验证子类即可完全不影响密码验证的方法,各个验证方法还可以分开管理,结构也非常清楚。

文章来源:http://fastfood.sinaapp.com/?p=1458

展开
收起
kun坤 2020-06-04 21:16:30 528 0
1 条回答
写回答
取消 提交回答
  • 懒婆娘的裹脚布######回复 @Xsank : 不用跟这种满嘴粗话、妄下结论的人浪费时间######也许你是个大牛,但是这样评论一点意义都没有,这是个技术论坛,不是给你撒泼的######排版不行 看着难受,

    这个好神奇 . 看不懂 谁给解释下 或者说下查Python文档应该用哪个关键词?

    ######你搜下python元类的相关资料吧,这个算是元类的一个应用###### 我没有记错的情况下,Python 3 中有re这个模块!为什么不考虑考虑用正则!用正则来验证长度和字符。
    ######re这个模块python2.x就有,这里主要是为了说明一种插件模式的使用方法######菜鸟路过######写的不错,不过排版怎么是这样,字符都连到一起去了######重新编辑了一下###### 有待改进
    PluginMount这个类可用一个list替代
    创建了Plugin对象只调用一次validate方法,有点多余
    可参考Django的内部验证机制
    https://github.com/django/django/blob/master/django/forms/fields.py ######最近正准备学习下django源码,多谢指点###### 插件在需要的时候再用,你可以在任何地方都用插件,任何过程,任何参数都可以用上插件,问题是这是不是你要面对的变化,或者就算遇到变化改一两行就可以了?
    建议先把东西做出来,再看哪里需要插件。如果一开始就规划插件,挺浪费时间的,除非这个业务你非常清晰,你知道你做的是有用的。 ######我觉得, 这个用Python的继承/多重继承会比较方便. 对于一个密码验证来说, __metaclass__黑魔法感略重. (仅说说, 还没认真思考)

    2020-06-08 09:45:47
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
From Python Scikit-Learn to Sc 立即下载
Data Pre-Processing in Python: 立即下载
双剑合璧-Python和大数据计算平台的结合 立即下载