在python中将方法添加到现有对象的任何优雅方法?

时间:2015-05-18 03:01:23

标签: python

经过大量搜索后,我发现有几种方法可以将绑定方法或未绑定类方法添加到现有实例对象

这些方式包括以下代码所采用的方法。

import types


class A(object):
    pass


def instance_func(self):
    print 'hi'

def class_func(self):
    print 'hi'

a = A()

# add bound methods to an instance using type.MethodType
a.instance_func = types.MethodType(instance_func, a)                # using attribute
a.__dict__['instance_func'] = types.MethodType(instance_func, a)    # using __dict__

# add bound methods to an class
A.instance_func = instance_func
A.__dict__['instance_func'] = instance_func

# add class methods to an class
A.class_func = classmethod(class_func)
A.__dict__['class_func'] = classmethod(class_func)

让我烦恼的是,输入函数的名称instance_funcclass_func两次。

是否有任何简单的方法可以将现有函数添加到类或实例而无需再次键入函数名称?

例如, A.add_function_as_bound_method(f)将是一个非常优雅的方式,可以将现有函数添加到实例或类中,因为该函数已具有__name__属性。

1 个答案:

答案 0 :(得分:46)

通常,当您使用虚线访问查找时,存储在对象词典中的函数不会自动转换为boundmethods。

也就是说,您可以使用functools.partial预绑定函数并将其存储在对象字典中,以便可以像方法一样访问它:

>>> from functools import partial
>>> class Dog:
        def __init__(self, name):
            self.name = name


>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> def bark(self):                 # normal function
        print('Woof! %s is barking' % self.name)

>>> e.bark = partial(bark, e)       # pre-bound and stored in the instance
>>> e.bark()                        # access like a normal method
Woof! Buddy is barking

这是一种向现有对象添加方法的一种优雅方式(无需更改其类并且不影响其他现有对象)。

评论的后续行动:

您可以使用辅助函数添加预绑定函数,只需一步:

>>> def add_method(obj, func):
        'Bind a function and store it in an object'
        setattr(obj, func.__name__, partial(func, obj))

像这样使用:

>>> add_method(e, bark)
>>> e.bark()
Woof! Fido is barking

希望这正是您所需要的: - )