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

Dan*_*ert 2 python function

我的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
Run Code Online (Sandbox Code Playgroud)

有没有办法避免重复定义这些函数而不影响执行速度?

aba*_*ert 6

你不需要一个宏; 函数是第一类对象,可以动态构建:

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')
Run Code Online (Sandbox Code Playgroud)

如果您愿意以某种方式标准化类型,您可以使这更简单.例如,如果这些每一个other_type事情是namedtuple-ish类型(的东西,有_fields___slots__或属性名称的其他一些迭代):

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

callback1 = make_callback(MsgX, msg_type_a)
callback2 = make_callback(MsgY, msg_type_b)
Run Code Online (Sandbox Code Playgroud)

或者,如果msg_types只知道如何从以下构造自己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)
Run Code Online (Sandbox Code Playgroud)

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

def make_callback(m_type):
    def callback(msg):
        m = m_type(msg)
        pub2.publish(m.to_other_type())
    return callback

callback1 = make_callback(MsgX, msg_type_a)
callback2 = make_callback(MsgY, msg_type_b)
Run Code Online (Sandbox Code Playgroud)

等等.所有基本的OO设计都适用于适当的Python(很难从你的玩具示例中知道什么是合适的),但你有许多反射/动态功能可以回归到它们不适用的时候.


这会影响性能吗?

好吧,你要么循环遍历2个事物的列表,要么添加额外的函数调用,这需要几纳秒.但这真的很重要吗?如果是这样,你几乎肯定想要改变你的设计,以便msg_type可以更便宜地构建类型(例如,在一次调用中),等等,并且在这样做时,你可以适应使这部分变得更容易的东西优化也是如此.