Python 从字典的键中提取类的方法

Python 从字典的键中提取类的方法,python,Python,下面脚本的思想是提取字典的键并将它们作为方法。这些键表示将由特定机器执行的自然语言命令 问题是: 要将可用命令(现在是方法)作为dir()的一部分或程序编辑过程中的完成部分查看,需要执行哪些操作 我想动态更改命令的值。 例如:machine2.move_x()打印'MV 12',但machine2.move_x('MV 20')生成TypeError:()不带参数(给定1)。 我试着玩弄各种各样的争论,但我没有弄对 机器控制 machine_cmds.py 您可以提供一个\uuuuu dir\u

下面脚本的思想是提取字典的键并将它们作为方法。这些键表示将由特定机器执行的自然语言命令

问题是:

  • 要将可用命令(现在是方法)作为
    dir()
    的一部分或程序编辑过程中的完成部分查看,需要执行哪些操作

  • 我想动态更改命令的值。 例如:
    machine2.move_x()
    打印
    'MV 12'
    ,但
    machine2.move_x('MV 20')
    生成
    TypeError:()不带参数(给定1)
    。 我试着玩弄各种各样的争论,但我没有弄对

  • 机器控制 machine_cmds.py
    您可以提供一个
    \uuuuu dir\uuuu
    方法来返回所有可用命令:

    def __dir__(self):
        return sorted(self)
    
    这包括
    dir()
    输出中对象的键

    为了支持设置,如果将lambda替换为嵌套函数会更容易;这样代码的可读性更高:

    def __getattr__(self, k):
        """ Defines the names of the methods to be the same as the
        keys of the dictionaries.
        """
        if k in self:
            def getter_setter(new_value=None):
                if new_value is None:
                    return self[k]
                self[k] = new_value
            return getter_setter
        raise AttributeError(k)
    
    我还将
    TypeError
    替换为更适用的
    AttributeError

    您可以直接返回值,并实现一个
    \uuu setitem\uuu
    来支持设置,而不是将其作为一个方法:

    def __getattr__(self, k):
        """ Defines the names of the methods to be the same as the
        keys of the dictionaries.
        """
        if k in self:
            return self[k]
        raise AttributeError(k)
    
    def __setattr__(self, k, v):
        if k in self:
            self[k] = v
        super(Machine, self).__setattr__(k, v)
    
    演示:


    您使用的是python2.7还是3+?如果您同时使用这两种语言,那么
    python
    标记就足够了。如果您只关心某个特定版本,请删除另一个特定于版本的标记(并保留
    python
    标记)。@Bakuriu:哦,好的!我不知道。我想如果你把这两个问题都说出来,我会向更广泛的听众提出这个问题。谢谢嗨,玛蒂恩!让我玩一下,我会给你回复的。我想做的另一件事是嵌入一些通信协议作为一种方法,这样在最后,比方说,
    machine1.home()
    命令将通过线路发送。有什么建议吗?如果这是一个问题,看起来是的,是的!从用户的角度来看,我想让事情简洁明了。例如:只需将机器与命令
    machine.command(value)
    一起选择,用户应该知道,只要按下
    Enter
    ,它就可以在这里扩展嵌套函数方法(让您轻松访问
    self
    闭包),是的。我看到,对于一个新值,您可以设置它,然后分两步调用它(1.
    m.home('new value')
    ,2.
    m.home()
    ),想法是输入一个新值,然后一步将其推到电线上,只要
    home('new value')
    在这种情况下,您可以立即返回它;这只是一个选择。
    def __getattr__(self, k):
        """ Defines the names of the methods to be the same as the
        keys of the dictionaries.
        """
        if k in self:
            def getter_setter(new_value=None):
                if new_value is None:
                    return self[k]
                self[k] = new_value
            return getter_setter
        raise AttributeError(k)
    
    def __getattr__(self, k):
        """ Defines the names of the methods to be the same as the
        keys of the dictionaries.
        """
        if k in self:
            return self[k]
        raise AttributeError(k)
    
    def __setattr__(self, k, v):
        if k in self:
            self[k] = v
        super(Machine, self).__setattr__(k, v)
    
    >>> class Machine(dict):
    ...     def __init__(self):
    ...         dct = {'poweron':'OUTP ON', 'home' : 'MV 0, 0', 'identify': '*IDN?'}
    ...         super(Machine, self).__init__(dct)
    ...     def __dir__(self):
    ...         return sorted(self)
    ...     def __getattr__(self, k):
    ...         if k in self:
    ...             def getter_setter(new_value=None):
    ...                 if new_value is None:
    ...                     return self[k]
    ...                 self[k] = new_value
    ...             return getter_setter
    ...         raise AttributeError(k)
    ... 
    >>> m = Machine()
    >>> dir(m)
    ['home', 'identify', 'poweron']
    >>> m.home
    <function Machine.__getattr__.<locals>.getter_setter at 0x10407fe18>
    >>> m.home()
    'MV 0, 0'
    >>> m.home('new value')
    >>> m.home()
    'new value'
    
    >>> class Machine(dict):
    ...     def __init__(self):
    ...         dct = {'poweron':'OUTP ON', 'home' : 'MV 0, 0', 'identify': '*IDN?'}
    ...         super(Machine, self).__init__(dct)
    ...     def __dir__(self):
    ...         return sorted(self)
    ...     def __getattr__(self, k):
    ...         if k in self:
    ...             return self[k]
    ...         raise AttributeError(k)
    ...     def __setattr__(self, k, v):
    ...         if k in self:
    ...             self[k] = v
    ...         super(Machine, self).__setattr__(k, v)
    ... 
    >>> m = Machine()
    >>> m.home
    'MV 0, 0'
    >>> m.home = 'new value'
    >>> m.home
    'new value'