如何避免Python中类似的函数定义?

2024-09-30 16:36:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我在Python代码中有很多非常相似的函数,如下所示:

def callback1(msg):
    m = MsgX(msg)
    a = msg_type_a()
    a.x = m.x
    pub2.publish(a)

def callback2(msg):
    m = MsgY(msg)
    b = msg_type_b()
    b.t = m.t
    b.u = m.u
    pub2.publish(b)

# ... and a couple more in the same fashion

有没有什么方法可以避免在不影响执行速度的情况下定义这些函数的重复?在


Tags: and函数代码indefmoretypemsg
3条回答

这不需要宏;函数是一级对象,可以动态构建:

def make_callback(m_type, other_type, *attrs):
    def callback(msg):
        m = m_type(msg)
        a = other_type()
        for attr in attrs:
            setattr(a, attr, getattr(m, attr))
        pub2.publish(a)
    return callback

callback1 = make_callback(MsgX, msg_type_a, 'x')
callback2 = make_callback(MsgY, msg_type_b, 't', 'u')

如果您愿意以某种方式标准化类型,您可以使其更简单。例如,如果这些other_type事物中的每一个都是namedtuple-ish类型(具有_fields_或{}或其他一些属性名的iterable):

^{pr2}$

或者,如果msg_type只知道如何从MsgTypes构造自己:

def make_callback(m_type, other_type):
    def callback(msg):
        m = m_type(msg)
        a = other_type(m)
        pub2.publish(a)
    return callback

callback1 = make_callback(MsgX, msg_type_a)
callback2 = make_callback(MsgY, msg_type_b)

或者,如果MsgTypes知道如何将自己转换为msg_types(甚至可能是动态生成的):

^{4}$

等等。所有基本的OO设计在适当的时候都可以在Python中使用(很难从你的玩具示例中知道什么是合适的),但是当它们不合适的时候,你有很多反射/动态特性可以使用。在


这会影响性能吗?在

好吧,您要么在一个包含两个事物的列表上循环,要么添加一个额外的函数调用,这需要几纳秒的时间。但这真的很重要吗?如果是这样的话,您几乎肯定希望更改您的设计,以便可以更便宜地构造msg_type类型(例如,在一个调用中),等等,并且在这样做的同时,您可以加入一些使这部分更容易优化的内容。在

听起来就像你在寻找类,它们允许你将方法和变量分配给一个结构相同的对象

没有宏,但可以创建一个定义另一个函数并返回它的函数:

def make_callback(msg_type, msg_type_func, attrs_to_copy):
    def callback(msg):
        m = msg_type(msg)
        x = msg_type_func()
        for attr in attrs_to_copy:
            setattr(x, attr, getattr(m, attr))
        pub2.publish(x)
    return callback

然后你会做一些类似的事情:

^{pr2}$

根据您的逻辑有多复杂,以及不同函数之间的差异,您可能需要编写一个类,将回调功能分解为多个部分(例如“设置属性”步骤和“发布步骤”),并提供一个单独的“go”方法来执行它们。另外,如果您知道什么组合是有意义的(例如,您知道MsgX总是与msg_type_a一起使用),那么您可以在某个字典中显式地显示该信息,并使用该字典从一个或几个“key”值派生调用的各个部分。在

相关问题 更多 >